1. Memory allocation

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 it but I've never actually used malloc() before, and it seems now's the best time to try!

- In the first place since I'm allocating memory, should I enter values for the total number of elements? [3000][3000] ?

- How should I set the l-value in the malloc declaration?

...... = malloc(sizeof(width*height));

Cheers all

Storm

2. Code:
```unsigned char *Image = malloc (3000*3000);
if (Image)
{
// code...
free (Image);
}```

3. ?

I'm not sure I've understood your short code example -

If I've got:

unsigned char Image[3000][3000];

should I declare:

unsigned char *Image = malloc(...);

???

Storm

4. Hi Salem,

Cheers,

Can you explain how the allocation code works. I love understanding the code rather than simply copying )

/* allocate it */

image = malloc( height * sizeof(*image) );

for ( r = 0 ; r < height ; r++ )
image[r] = malloc( width * sizeof(**image) );

5. Storm,

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).

6. Thanks for the explanation Cat,

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:

for ( r = 0 ; r < height ; r++ )
image[r] = malloc( width * sizeof(**image) );
|

Size image is defined as unsigned char anyway, could I write, sizeof(*image) ?

Storm

7. I tried to use Salem's code and I got an error because malloc is a void function and the code is trying to get a return value. Is this an error in the compiler or what?

http://www.rt.com/man/malloc.3.html

8. 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.

9. 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.

10. free ?

Hi Elixia.

I do check for the NULL pointer:

What I would like to know now is how to retrieve the amount of memory actually allocated (without obviously using height and width multiplied by unsigned char!).

Storm

11. >>how to retrieve the amount of memory actually allocated
That'll be either nothing (in the case of an error) or the full amount you asked for in the malloc() call.

If you're asking how to find out how much memory a pointer points to, the answer is you can't, unless you record it yourself somehow.

12. regarding return value of malloc

I believe that malloc returns actual address for ordinary pointers and relative addresses for far and huge pointers...is n't it so?

13. Nice job of bumping a 9 month old thread there

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