double** theArray;Voila!
theArray = (double**) malloc(arraySizeX*sizeof(double*));
for (int i = 0; i < arraySizeX; i++)
theArray[i] = (double*) malloc(arraySizeY*sizeof(double));
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
Then, inside the code, i would use something like
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;
}
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:
Saad, T. "2D Arrays in C Using malloc".
Weblog entry from
Please Make A Note.
http://pleasemakeanote.blogspot.com/2008/06/2d-arrays-in-c-using-malloc.html
Hello.
ReplyDeleteThanks 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.
Thanks for your comment.
ReplyDeleteThe (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.
UPDATE: There was a typo in the first code snippet, and now it is corrected.
ReplyDeleteThanks very much for this. Actually the entire blog is so helpful!!
DeleteThanks for this!
ReplyDeletethanks .. been really helpful :)
ReplyDeleteThank you sir!
ReplyDeleteThank you so much!
ReplyDeleteVery helpful :D
Thanks very helpfull :)
ReplyDeleteI 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.
ReplyDeleteplease see.....
http://c-faq.com/malloc/cast.html
and
http://c-faq.com/malloc/mallocnocast.html
please read the section "Don't cast the value returned by malloc or calloc:" of link... http://prokutfaq.byethost15.com/DynamicMemoryAllocation
ReplyDeleteIt is quite informative.
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.
ReplyDeletegreat work
ReplyDeletethanks
but be careful because it does not result an array like the one we have when we declare it.
ReplyDeleteWhen 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())
This technique leads to memory fragmentation and is useless for caching. Better to allocate all dimensions in one malloc() if possible.
ReplyDeleteOr, better:
Deleteint (*table)[columns] = malloc(rows * sizeof *table);
thanks!
ReplyDeleteThanks!!! Good Job... But could you tell me something? How do you fill with random numbers a 2D array after creating it?
ReplyDeletei only know how to do it with 1D array
If i may say so:
Deletesrand(time(NULL));
for(i=0; i< X; i++)
{
for(j=0; j< Y; j++)
{
array2d[i][j] = rand%MAXVAL;
}
}
Great use with this..!
ReplyDeleteBut tell me why we use the casting as (double**)
please make note about use of casting..
thank you .
1st hit on Google, best way to refresh my knowledge!
ReplyDeleteThumbs up, sir.
thax
ReplyDeleteAbout 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.
ReplyDeleteWhen 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.
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.
ReplyDeleteIf you are coding C in Visual Studio, you actually do need the cast.
DeleteVery helpful example, thank you to the author.
Thank you very helpful first hit on google.
Delete