Thread: Dynamic Memory Allocation (Seg. Fault)

1. Dynamic Memory Allocation (Seg. Fault)

Hi everyone, first time user here. I just want to know if anyone can help me with a very simple piece of code.

In a nutshell, I would like to dynamically allocate memory for a 2D array using new and delete. (I know I know, it is a common question but please keep reading). Instead of dynamically allocating the memory in the main() function, I would like to pass the 2D array to a function called "initArray(int *array[], int *numrows, int *numcols)". Once I initialize the array, I return back to the main () function and print a random value, say cout << array[1][1] << endl;. However, I received a segmentation fault which did not make any sense.

Below is the entire code of my program:

Code:
```#include <iostream>

using namespace std;

//Function Prototype
void initArray (int *array[], int *numrows, int *numcols);

//Main Function
int main ()
{
int **a;

int numrows = 5, numcols =5;

//Pass the double pointer "a" along with the addresses of numrows and numcols
initArray (a, &numrows, &numcols);

//when returning from function initArray(), print out element at row 1, column 1
cout << a[1][1] << endl;

return (0);

}

void initArray (int *array[], int *numrows, int *numcols)
{

int i, j;

array = new int* [*numrows];

for (i = 0; i < *numrows; i++)
{
array[i] = new int [*numcols];
}

for (i = 0; i < *numrows; i++)
{
for (j = 0; j < *numcols; j++)
array[i][j] = i*j;
}

//print the element at row 1 and column 1
cout << array[1][1] << endl;
}```
For some strange reason, the cout statement in my initArray function prints normally whereas the same cout statement back in my main() function, it yells at me that I have a segmentation fault.

If my logic is correct, I would assume that passing double pointer "a" essentially passes the address of where the double pointer is located in memory. My initArray function receives the address (int *array[] parameter), it should start initializing the matrix with the values i*j and writes it in memory. What I don't understand that why is the cout function does not cause a segmentation fault in the initArray function but occurs in my main() function.

Would someone please give me a solution or an explanation to this?

Thanks and with sincerest regards

2. array (within the scope of the initArray function) is a copy of the address/value passed in. Once you reassign this value in the first new call, the value stored locally within the initArray function is modified as desired however it does not affect the value stored in the calling function (the variable a in main). The solution to that is to pass the address of a into the function and have the function accept a pointer to a pointer to a pointer (or a reference to a pointer to a pointer).

There is also no need to pass the row/column values by pointer, they are not being modified within the initArray function, only accessed.

Now, I'm off to play Halo 3.

3. would you kindly please post the "fix" code on here? Some reason I tried doing your suggestion and it didn't work.

Thanks and with sincerest regards

4. I would suggest that instead of passing in an int*[], you change the return type to int*[] and return 'array', assigning it to 'a' in main.
numrows and numcols should not be pointers. Did you fix that?

Note that if this were proper C++ code, initArray would instead be the constructor of some class and there would be no need to pass an int*[] into or out of it.

5. Originally Posted by iMalc
I would suggest that instead of passing in an int*[], you change the return type to int*[] and return 'array', assigning it to 'a' in main.
numrows and numcols should not be pointers. Did you fix that?

Note that if this were proper C++ code, initArray would instead be the constructor of some class and there would be no need to pass an int*[] into or out of it.
yup I fixed the numrows and numcols,

Well I tried that method and some reason I'm still getting segmentation faults but this time it is in my initArray function.

After the third iteration, it yells at me that I have a segmentation fault. Once again, am I missing something here?

Code:
```#include <iostream>

using namespace std;

int** initArray (int *(**b), const int numrows, const int numcols);

int main ()

{

int **c;

c = initArray(&c, 5, 5);

return (0);

}

int** initArray (int *(**array), const int numrows, const int numcols)
{
int i, j;

*array = new int * [numrows];

cout << "Hello Hello" << endl;

for (i = 0; i < numrows; i++)
{
*array[i] = new int [numcols];
cout << "Iteration " << i << endl;
}

for (i = 0; i < numrows; i++)
{
for (j = 0; j < numcols; j++)
*array[i][j] = i*j;
}

return *array;

}```

6. Using a reference:
Code:
```#include <iostream>

using namespace std;

void initArray (int ** &array, const int numrows, const int numcols);

int main ()
{
int **c;

initArray(c, 5, 5);

return 0;
}

void initArray (int ** &array, const int numrows, const int numcols)
{
int i, j;

array = new int * [numrows];

cout << "Hello Hello" << endl;

for (i = 0; i < numrows; i++)
{
array[i] = new int [numcols];
cout << "Iteration " << i << endl;
}

for (i = 0; i < numrows; i++)
{
for (j = 0; j < numcols; j++)
array[i][j] = i*j;
}

}```

7. Hi,

Thanks for all the replies. I took up iMalc's advice, sample code below if anyone needs it:

Code:
```#include <iostream>

using namespace std;

int** initArray (int **b, const int numrows, const int numcols);

int main ()

{

int **c;

c = initArray(c, 3 , 3 );

int i, j = 0;

for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
cout << c[i][j] << " " ;

cout << endl;
}

//cout << c[2][2] << endl;

return (0);

}

int** initArray (int **array, const int numrows, const int numcols)
{
int i, j;

array = new int * [numrows];

cout << "Hello Hello" << endl;

for (i = 0; i < numrows; i++)
{
array[i] = new int [numcols];
cout << "Iteration " << i << endl;
}

for (i = 0; i < numrows; i++)
{
for (j = 0; j < numcols; j++)
{
array[i][j] = i*j;
cout << "I'm over here" << endl;
}
}

return array;

}```
To hk_mp5kpdw:

Thanks for the solution , however I'm still not understanding the parameter in your modified function prototype as posted below:

Code:
`void initArray (int ** &array, const int numrows, const int numcols)`
Does this mean that there will be a pointer to a pointer of the address of array? Because when passing in a double pointer "c" (lets just say), I would assume that int ** &array would receive the address where c is pointing at. What is really throwing me off is why would you need the address of array?

8. The & in the function parameter indicates that it is a reference. That means that any changes to that double pointer will be reflected in the original double pointer in the calling function.

BTW, is there a reason you're not using vector instead of a dynamic array?

9. Originally Posted by Daved
The & in the function parameter indicates that it is a reference. That means that any changes to that double pointer will be reflected in the original double pointer in the calling function.

BTW, is there a reason you're not using vector instead of a dynamic array?
Thanks for the explanation.

As for your question, well I'm kinda developing a CAD tool which stores some variable amounts of nodes for each position in the array. Such that array[0] represents node 0, which will contain a pointer to a link list that contains the connected nodes that comes out of node 0.

And plus, I'm doing this in C++ because I'm more familiar with it but it has been awhile since I programmed. I am kinda curious what's this vector talk is all about and how this can relate to what I'm doing.

Thanks

10. I am kinda curious what's this vector talk is all about and how this can relate to what I'm doing.
Well, it's like this: you say you're using C++, but you're really using C with a few C++ idiosyncrasies (specifically, new and cout, and now references). You use pointers for pass-by-ref (you didn't immediately recognize a reference), you use raw pointers, you manage your own memory, you're not writing object-oriented code, and you don't what vector is.

Nothing wrong with writing C, but it's not C++.

That said.

vector is a class (template) in the C++ standard library. It is a dynamically resizable array that does the memory management for you. You could use a vector of vectors to achieve what you're doing currently, with much less hassle.

Which doesn't solve the other problem, namely that allocating an array of pointers (or creating a vector of vectors) is a very inefficient way of creating true 2d arrays. What you really want is Boost.Multi_Array, which is an efficient multi-dimensional array that does the memory management for you and still allows you to choose things like memory layout (row-major or column-major).

11. Originally Posted by CornedBee
Well, it's like this: you say you're using C++, but you're really using C with a few C++ idiosyncrasies (specifically, new and cout, and now references). You use pointers for pass-by-ref (you didn't immediately recognize a reference), you use raw pointers, you manage your own memory, you're not writing object-oriented code, and you don't what vector is.

Nothing wrong with writing C, but it's not C++.

That said.

vector is a class (template) in the C++ standard library. It is a dynamically resizable array that does the memory management for you. You could use a vector of vectors to achieve what you're doing currently, with much less hassle.

Which doesn't solve the other problem, namely that allocating an array of pointers (or creating a vector of vectors) is a very inefficient way of creating true 2d arrays. What you really want is Boost.Multi_Array, which is an efficient multi-dimensional array that does the memory management for you and still allows you to choose things like memory layout (row-major or column-major).
Wow, I didn't expect a lecture on how not to use a language.

Well I intend on getting better in the C++ language and be able to take advantage of these available libraries that the language provides us. At any rate, thanks for your explanation on vectors. I think I will incorporate them in my future programming problems.