Memory allocation

This is a discussion on Memory allocation within the C Programming forums, part of the General Programming Boards category; Hi all,
I've got this 2-D array to store unsigned character image data.
Image[3000][3000];
I'd like to allocate memory to ...

Salem's code creates an "array of arrays". Think of it this way -- image points to an array (of 3000 elements in your case), each element of which is a pointer to an array of 3000 elements. You have the effect of a 2D array.

So, when you say "array[40][25]", the compiler first looks at the 41st element of array. The 41st element (array[40]) is itself an array, and so the compiler then looks at the 26th element of that array.

One thing which is sometimes a problem with this method is that there is no guaranteed ordering of memory. Each row is allocated independantly, so there is no guarantee as to their relative positions in memory. In other words, in a 640x480 array, arr[1][0] is not necessarily located (in memory) immediately after arr[0][479]. There is a way to use a similar method, however, to guarantee that the memory is contiguous, if you require it (as some graphical API calls will). If you don't care about the relative positions in memory, then either way is equally good.

I'll post the other way (the contiguous memory method) if you want to see it).

I understand 2-D arrays, work with quite alot - what I was after is the actual malloc part. I've practically understood it but I'm still not sure why Salem used **image in the sizeof part of the for loop:

malloc returns a void *, not void. If you get an error (can't convert void * to unsigned char * or something similar), then you're using a C++ compiler, not a C compiler. It's legal C but not legal C++. If you have a C++ compiler, many of them can be told to compile code as C, but you usually need to explicitly tell the compiler that.

Storm:

"sizeof(image)" is the same as saying "sizeof(unsigned char **)" because that's what image is. So, "sizeof(*image)" is the same as "sizeof(unsigned char *)", and "sizeof(**image)" is the same as "sizeof(unsigned char)". The advantage here is that, even if you change the type of image (say, you make it an int**), the code requires no further changes.

Don't forget that you will need to add error checking to salem's code - for example, malloc can return null, which basically means memory allocation failure. At that point, you should free any memory you've already allocated and return an error status to the caller of the function.

>Nice job of bumping a 9 month old thread there
Indeed, most impressive.

>Does malloc return the actual address or the relative address?
malloc returns a pointer to at least as much memory as you requested (on success). How that memory is actually mapped is irrelevant unless you plan on writing your own implementation of malloc, but at that point you've exceeded the scope of standard C and entered the realm of platform-dependence. Furthermore, C doesn't know what a far or huge pointer is. Far and huge pointers are extensions for old DOS compilers meant to overcome the segment size limit of a program's address space.

If you really want to know the answer to this question, I suggest asking someone with intimate familiarity with a specific compiler that supports far and huge pointers.