## Wednesday, June 11, 2008

### 2D Arrays in C Using malloc

Pointers can be easily used to create a 2D array in C using malloc. The idea is to first create a one dimensional array of pointers, and then, for each array entry, create another one dimensional array. Here's a sample code:
`double** theArray;theArray = (double**) malloc(arraySizeX*sizeof(double*));for (int i = 0; i < arraySizeX; i++)   theArray[i] = (double*) malloc(arraySizeY*sizeof(double));`
Voila!

What I usually do is create a function called Make2DDoubleArray that returns a (double**) and then use it in my code to declare 2D arrays here and there
`double** Make2DDoubleArray(int arraySizeX, int arraySizeY) {double** theArray;theArray = (double**) malloc(arraySizeX*sizeof(double*));for (int i = 0; i < arraySizeX; i++)   theArray[i] = (double*) malloc(arraySizeY*sizeof(double));   return theArray;} `
Then, inside the code, i would use something like
`double** myArray = Make2DDoubleArray(nx, ny);`
Voila!

Of course, do not forget to remove your arrays from memory once you're done using them. To do this
`for (i = 0; i < nx; i++){   free(myArray[i]);}free(myArray);`

UPDATE: JULY 10, 2008
As was noted by an anonymous comment, a great advantage of declaring a 2D array in this manner is the ability to use it as myArray[i][j], a very intuitive form.

Cite as:

1. Hello.

Thanks for the short but very useful code snippets you present here. But I think there is a little mistake: In line 2 of the first snippet and also in line 3 of the second one, it should be
"theArray = malloc(arraySizeX*sizeof(double*));",
i.e. without the "(double*)" in front of malloc.
Also you could mention that the pro about this way of building up 2D arrays using malloc is that you can use the usual "myArray[i][j]" command in the main function.

Thanks again for this great entry and especially the second code snippet defining the function.

The (double*) is needed in front of the malloc because malloc is defined as a (void*) pointer, and thus you will need to cast it as (double*) or any other datatype for that matter.

I agree with your comment on the use of the 2D array (i.e. myArray[i][j]). It is now added to the post.

3. UPDATE: There was a typo in the first code snippet, and now it is corrected.

1. Thanks very much for this. Actually the entire blog is so helpful!!

4. Thanks for this!

5. thanks .. been really helpful :)

6. Thank you sir!

7. Thank you so much!

9. I think, there is no need of explicit casting in line 4 and also in line 2. It will automatically converted into (double**) and (double*) in line 2 and line 4 respectively by implicit type conversion.
http://c-faq.com/malloc/cast.html
and
http://c-faq.com/malloc/mallocnocast.html

10. please read the section "Don't cast the value returned by malloc or calloc:" of link... http://prokutfaq.byethost15.com/DynamicMemoryAllocation
It is quite informative.

11. Sorry to add this to a very old thread, but I believed that, to make such code compatible with C++ compilers (should you have to compile C code on a C++ compiler), a casting of the initially void pointer returned by malloc was indeed required.

12. great work
thanks

13. but be careful because it does not result an array like the one we have when we declare it.
When we declare an array the array makes sense as a whole. Even if the name of array is a pointer that its VALUE is the address of the first element of the array but is a pointer about the array as a whole not a pointer to the first element.
In this article's code Make2DDoubleArray does not return a pointer to 2D array but a pointer to a pointer. It isn't the same.
For this reason in this situation the value of theArray is not equal to theArray[0] as we have when an array declares normal (without malloc())

14. This technique leads to memory fragmentation and is useless for caching. Better to allocate all dimensions in one malloc() if possible.

1. Or, better:

int (*table)[columns] = malloc(rows * sizeof *table);

15. Thanks!!! Good Job... But could you tell me something? How do you fill with random numbers a 2D array after creating it?
i only know how to do it with 1D array

1. If i may say so:

srand(time(NULL));

for(i=0; i< X; i++)
{
for(j=0; j< Y; j++)
{
array2d[i][j] = rand%MAXVAL;
}
}

16. Great use with this..!
But tell me why we use the casting as (double**)
thank you .

17. 1st hit on Google, best way to refresh my knowledge!
Thumbs up, sir.

18. About the function code, it's not correct to return the pointer that is declared inside the function. Maybe, it will work for low memory usage, but the memory space that it's declared, after the end of the function will not be legal.
When a function is completed it's memory is not part of the program any more. So you have to declare the variable outside the function, wherever you want to use it, in the main or any other function depended on the prefered lifetime.

19. Casting the return value of malloc in C is just wrong. You are using a C++ compiler if you are getting an error because, in C++, there exists no implicit conversion from void* to whatever*. That is not true in C, and casting the result can actually hide an error in your code. The cast will, in older compilers, suppress n error if you forgot to include . In C you do not make the cast, period.

1. If you are coding C in Visual Studio, you actually do need the cast.

Very helpful example, thank you to the author.