Reputation: 1746
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
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
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
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
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