JMzance
JMzance

Reputation: 1746

Malloc in function in c++

Hi I'm trying to neaten up my code by moving all of my Malloc calls (ans subsequent malloc checks) into one routine which looks like:

int Malloc2D(int n, int m, double** array_ptr) {

array_ptr = (double**) malloc(n * sizeof(double*));
if (array_ptr == NULL) {
    std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
    return -1;
}
for (int i = 0; i < n; i++) {
    array_ptr[i] = (double*) malloc(m * sizeof(double));
    if (array_ptr[i] == NULL) {
        std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
        return -1;
    }
}

return 0;
}

But when in main() I do something like:

double** test;
if(Malloc2d(10, 20, test) == -1) return -1;

and then try and use the array in main I get a segfault? Anyone got any ideas? Jack

Upvotes: 0

Views: 171

Answers (4)

Mats Petersson
Mats Petersson

Reputation: 129524

Since you are passing a double **array_ptr it won't modify the pointer outside the function.

In C++, you could fix it by making it a reference (and use new, since it's C++)

int Malloc2D(int n, int m, double**& array_ptr) {

array_ptr = new double*[n]);
if (array_ptr == NULL) {
    std::cout << "ERROR! new failed on line " << __LINE__ << "..." << std::endl;
    return -1;
}
for (int i = 0; i < n; i++) {
    array_ptr[i] = new double[m];
    if (array_ptr[i] == NULL) {
        std::cout << "ERROR! new failed on line " << __LINE__ << "..." << std::endl;
        return -1;
    }
}

return 0;
}

Or, in C-style fashion, we could use another pointer indirection (using &test in the calling code to pass the address of the double ** test).

int Malloc2D(int n, int m, double*** array_ptr) {

*array_ptr = (double**) malloc(n * sizeof(double*));
if (array_ptr == NULL) {
    std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
    return -1;
}
for (int i = 0; i < n; i++) {
    (*array_ptr)[i] = (double*) malloc(m * sizeof(double));
    if ((*array_ptr)[i] == NULL) {
        std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
        return -1;
    }
}

return 0;
}

Or you could simply return the pointer to the array in the first place - but this would require some minor changes to the calling code:

double** Malloc2D(int n, int m) {

double** array_ptr;
array_ptr = (double**) malloc(n * sizeof(double*));
if (array_ptr == NULL) {
    std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
    return NULL;
}
for (int i = 0; i < n; i++) {
    array_ptr[i] = (double*) malloc(m * sizeof(double));
    if (array_ptr[i] == NULL) {
        std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
        return NULL;
    }
}

return array_ptr;
}

Upvotes: 2

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158639

and then try and use the array in main I get a segfault

The problem is that you are not modifying array_ptr since it is being passed by value. One possible solution would be to pass it by reference:

int Malloc2D(int n, int m, double** &array_ptr)
                                    ^

Upvotes: 1

ChristopheLec
ChristopheLec

Reputation: 856

You should pass a pointer or a reference on your double array_ptr. Here, it is copied, and only the copy is modified.

int Malloc2D(int n, int m, double** &array_ptr)

Upvotes: 1

abelenky
abelenky

Reputation: 64740

C and C++ are pass-by-value.
So changes made to array_ptr inside your function Malloc2D are not visible outside the function.

You want to pass a pointer to test, and modify the value of that.
(which leads to a triple-pointer; confusing, but not unmanageable)

int Malloc2D(int n, int m, double*** pOutput)
{
    double** array_ptr
    array_ptr = (double**) malloc(n * sizeof(double*));
    if (array_ptr == NULL) {
        std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
        return -1;
    }
    for (int i = 0; i < n; i++) {
        array_ptr[i] = (double*) malloc(m * sizeof(double));
        if (array_ptr[i] == NULL) {
            std::cout << "ERROR! malloc failed on line " << __LINE__ << "..." << std::endl;
            return -1;
        }
    }

    *pOutput = array_ptr;
    return 0;
}

Then to use the function, pass the address of test:

double** test;
if(Malloc2d(10, 20, &test) == -1) return -1;

Upvotes: 1

Related Questions