-1

i have to do a dynamic-allocation (double-pointer) in a function and then i have to put in the matrix some number and then deallocate it

i have also tried to write **matrice instead of *(matrice[i]) in first function when i have to create a matrix after the first dynamic-allocation but it is always wrong and in this case the program exit after i insert the first line of the matrix

#include <iostream>
#include <stdlib.h>

using namespace std;

void allocaMatrice(int *** matrice,int * r,int * c);
void leggiMatrice(int ** matrice,int r,int c);
void scriviMatrice(int ** matrice,int r,int c);
void deallocaMatrice(int ** matrice,int r);

int main (){
int **matrice;
    int r, c;
    allocaMatrice(&matrice,&r,&c);
    leggiMatrice(matrice,r,c);
    scriviMatrice(matrice,r,c);
    deallocaMatrice(matrice,r);

    cin.get();
    return 0;
}

void allocaMatrice(int *** matrice,int * r,int * c){
    cout<<"Dimmi il numero di righe della matrice"<<endl;
    cin>>*r;
    while(cin.get()!='\n');
    cout<<"Dimmi il numero di colonne della matrice"<<endl;
    cin>>*c;
    while(cin.get()!='\n');

    *matrice=(int **) calloc (*r,sizeof(int));

    for(int i=0;i<*c;i++){
        *matrice[i]=(int *) malloc ((*c)*sizeof(int));
    }   
}

void leggiMatrice(int ** matrice,int r,int c){
    for(int i=0;i<r;i++){
        for(int j=0;j<c;j++){
           cout<<"Dimmi l'elemeno alla riga e colonna corrente"<<endl;
            cin>>matrice[i][j];
            while(cin.get()!='\n');
        }
    }
}

void scriviMatrice(int ** matrice,int r,int c){

for(int i=0;i<r;i++){
    for(int j=0;j<c;j++){
        cout<<matrice[i][j]<<"\t";
    }
    cout<<endl;;
}

}

void deallocaMatrice(int ** matrice,int r){
    int i;
    for(i=0;i<r;i++){
       free((*matrice)+1);
    }
    free(matrice);
}

the debug error is "Program received signal SIGSEGV, Segmentation fault"

ric
  • 69
  • 2
  • 8
  • function allocaMatrice is the dynamic-allocation ,leggiMatrice is the matrix insert,scriviMatrice is the print and deallocaMatrice is the deallocation – ric Oct 30 '19 at 19:24
  • 1
    Why are you using `malloc` and `calloc` in a C++ program? Please stop. Why are you doing manual memory management *at all* when you could just be using `std::array` or `std::vector`? And if you *insist* on not using containers, then, *please*, at least use smart pointers (`std::unique_ptr`/`std::shared_ptr`). And remember, "more stars don't mean you're a better programmer" - more likely, quite the opposite. I'd never (or at least not without a *really* good reason) let anything like `void allocaMatrice(int *** matrice,int * r,int * c);` pass code review. – Jesper Juhl Oct 30 '19 at 19:28
  • When you have your code corrected and working, consider asking for input on how to make it better at [Code Review](https://codereview.stackexchange.com/). – user4581301 Oct 30 '19 at 19:32
  • i'm using malloc and calloc because this is an homework exercise and the prof have just taught us malloc calloc new and double pointer so in this exercise we have to use these function. in a another version i have to use new for example.As far i know malloc and calloce can be used also in c++ . – ric Oct 30 '19 at 19:34
  • i use the third-pointer, so to speak,because i have to make a void function to allocate the matrix , if i use a type of return int ** it would be more easy – ric Oct 30 '19 at 19:38

3 Answers3

1

The line

*matrice=(int **) calloc (*r,sizeof(int));

is not right. It allocates memory for *r number of ints. You need to allocate memory for *r number of int*s (pointers not ints)

It needs to be:

*matrice=(int **) calloc (*r, sizeof(int*));

You're using C++ as the language tag but your code is designed to work like a C program. Use C++ properly and make your program cleaner.

  1. Use std::vector for containers and remove the need to manage memory.
  2. Use reference types to pass arguments between functions.

thus:

#include <iostream>
#include <vector>

template<typename T>
using VecVec = std::vector<std::vector<T>>;
using IntVecVec = VecVec<int>;

void allocaMatrice(IntVecVec& matrice);
void leggiMatrice(IntVecVec& matrice);
void scriviMatrice(IntVecVec const& matrice);

// Not necessary.
// void deallocaMatrice(int ** matrice,int r);

int main() {
    IntVecVec matrice;
    allocaMatrice(matrice);
    leggiMatrice(matrice);
    scriviMatrice(matrice);

    std::cin.get();
}

void allocaMatrice(IntVecVec& matrice) {
    int righe, colonne;
    std::cout << "Dimmi il numero di righe della matrice\n";
    std::cin >> righe;
    //while (cin.get() != '\n');???
    std::cout << "Dimmi il numero di colonne della matrice\n";
    std::cin >> colonne;
    //while (cin.get() != '\n');??

    matrice.resize(righe, std::vector<int>(colonne, 0));
}

void leggiMatrice(IntVecVec& matrice) {
    for (auto& riga : matrice) {
        for (auto& elemeno : riga) {
            std::cout << "Dimmi l'elemeno alla riga e colonna corrente\n";
            std::cin >> elemeno;
            //while(cin.get()!='\n'); // what does this add?
        }
    }
}

void scriviMatrice(IntVecVec const& matrice) {
    for (auto const& riga : matrice) {
        for (auto const& elemeno : riga) {
            std::cout << elemeno << '\t';
        }
        std::cout << '\n';
    }
}
JHBonarius
  • 10,824
  • 3
  • 22
  • 41
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • i can't use std::vector, i have to do necessarily like – ric Oct 30 '19 at 19:45
  • @ric, I understand. It's unfornunate that you are forced to use C++ like C. Terrible. – R Sahu Oct 30 '19 at 19:46
  • i know your method is more easy but unfortunately the exercise ask what i wrote – ric Oct 30 '19 at 19:47
  • Uhmm... what's with your for loops? Either use iterators or range based for loops please... – JHBonarius Oct 30 '19 at 20:15
  • @JHBonarius, good call although it's moot as far as the OP is concerned. – R Sahu Oct 30 '19 at 20:17
  • sorry @JHBonarius what do you mean with use iterators or range based for loops? – ric Oct 30 '19 at 20:27
  • @ric https://stackoverflow.com/questions/4925148/c-proper-way-to-iterate-over-stl-containers#21345143 <-- though a bit old. But don't worry. This stuff is probably too complex for your terrible professor... – JHBonarius Oct 30 '19 at 21:05
0

I'll append the previous answer with an important concept in C++: classes. You use C++ for object oriented programming. Else you could as well use C.

See if you can follow.

#include <iostream>
#include <vector>

template<typename T>
class Matrice {
private:
    std::vector<std::vector<T>> matrice;
public:
    void alloca();
    void leggi();
    void scrivi() const;
};

int main() {
    Matrice<int> matrice;

    matrice.alloca();
    matrice.leggi();
    matrice.scrivi();

    std::cin.get();
}

template<typename T>
T Read() {
    T output;
    std::cin >> output;
    return output;
}

template<typename T>
void Matrice<T>::alloca() {
    std::cout << "Dimmi il numero di righe della matrice\n";
    auto righe = Read<int>();

    std::cout << "Dimmi il numero di colonne della matrice\n";
    auto colonne = Read<int>();

    matrice.resize(righe, std::vector<T>(colonne, 0));
}

template<typename T>
void Matrice<T>::leggi() {
    for (auto& riga : matrice) {
        for (auto& elemeno : riga) {
            std::cout << "Dimmi l'elemeno alla riga e colonna corrente\n";
            std::cin >> elemeno;
        }
    }
}

template<typename T>
void Matrice<T>::scrivi() const {
    for (auto const& riga : matrice) {
        for (auto const& elemeno : riga) {
            std::cout << elemeno << '\t';
        }
        std::cout << '\n';
    }
}
JHBonarius
  • 10,824
  • 3
  • 22
  • 41
0

I think I found the solution : in the function allocaMatrice after the first dynamic-allocation (*matrice=(int **) calloc (*r,sizeof(int));) i made a mistake in the second dynamic-allocation, instead of :

for(int i=0;i<*c;i++){
        *matrice[i]=(int *) malloc ((*c)*sizeof(int));
}

i should have written this:

for(int i=0;i<*c;i++){
        (*matrice)[i]=(int *) malloc ((*c)*sizeof(int));
}   

So the final progam would be this: #include #include

using namespace std;

void allocaMatrice(int *** matrice,int  &r,int &c);
void leggiMatrice(int ** matrice,int r,int c);
void scriviMatrice(int ** matrice,int r,int c);
void deallocaMatrice(int ** matrice,int r);

int main (){
   int **matrice;
   int r, c;
   allocaMatrice(&matrice,r,c);
   leggiMatrice(matrice,r,c);
   scriviMatrice(matrice,r,c);
   deallocaMatrice(matrice,r);

   cin.get();
   return 0;
}

void allocaMatrice(int *** matrice,int  &r,int &c){
    int i;
    cout<<"Dimmi il numero di righe della matrice"<<endl;
    cin>>r;
    while(cin.get()!='\n');
    cout<<"Dimmi il numero di colonne della matrice"<<endl;
    cin>>c;
    while(cin.get()!='\n');

   *matrice=(int **) calloc (r, sizeof(int*));
   cout<<"c";
   for(i=0;i<c;i++){
       (*matrice)[i]=(int *) calloc (c,sizeof(int));
   }    
}

void leggiMatrice(int ** matrice,int r,int c){
    for(int i=0;i<r;i++){
        for(int j=0;j<c;j++){
            cout<<"Dimmi l'elemeno alla riga "<<i+1<<" e alla colonna     "<<j+1<<endl;
            cin>>matrice[i][j];
            while(cin.get()!='\n');
        }
    }
}

void scriviMatrice(int ** matrice,int r,int c){

    for(int i=0;i<r;i++){
        for(int j=0;j<c;j++){
            cout<<matrice[i][j]<<"\t";
        }  
        cout<<endl;;
    }

}

void deallocaMatrice(int ** matrice,int r){
    int i;
    for(i=0;i<r;i++){
        free((*matrice)+1);
    }
    free(matrice);
}
ric
  • 69
  • 2
  • 8