What's wrong with my C code for dynamic memory allocation/free for Multi-dimensional array?

You should malloc just one chunk of memory with size of the product of the numbers in dim_len .

Up vote 0 down vote favorite share g+ share fb share tw.

I'm working on debugging a C program. A huge data array with 3 dimensionals is needed. I developed two function for memory allocation/free.

Mm() is designed for allocation, with reference to an array which records the size of each dimension (you may see it in main()). Ff() is used for freeing memory. I tested my code with top command after fr() execution.

It shows memory is not freed. Can anyone shed light on it? Thanks in advance!

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 28338 fsdiag 25 0 165m 164m 1208 R 63.2 26.0 0:00.33 a. Out 3439 root 15 0 31740 1180 21m S 1.9 0.2 10:56.47 X int main(){ unsigned char ***arr; int dim_len4={8832,256,64,0}; // for 3-D array, 0 is mark of tail unsigned char *p; mm( &p, dim_len, 0); arr = (unsigned char ***)p; ff( (unsigned char **)&arr, dim_len); while(1){} return 0; } void mm( unsigned char **a, int dim_len, //dimension size array guarded by 0 in the tail unsigned char data){ //preset data if( *dim_len ){ int i; switch(*(dim_len+1)){ case 0://when allocate memory for unsigned char *a = malloc( sizeof(unsigned char) * (*dim_len)); break; default://when allocate memory for pointers *a = malloc( sizeof(unsigned char *) * (*dim_len)); for( i=0; i.

Very often, free just marks the freed memory as usable; it doesn't return it to the OS. – pmg Jul 5 '11 at 10:05 Note that, since the array dimensions in this example code are known at compile-time, you could do typedef unsigned char twoD25664; twoD *p = malloc(8832*sizeof(*p));. But that may not be the case in your real code.

– Steve Jessop Jul 5 '11 at 11:42.

You should malloc just one chunk of memory with size of the product of the numbers in dim_len. Your allocated data is fragmented and bigger than it should be and I'm struggling to imagine any scenario where your code has any benefits.

Definitely. Just one block of contiguous memory, and you access it with strides, element(i, j, k) = bufi + DIM1 * j + DIM2 * k;. – Kerrek SB Jul 5 '11 at 10:45 The "benefit" of using arrays of pointers in place of proper multidimensional arrays, is that the syntax to access them looks like a multidimensional array: arrijk instead of arrDIM1*DIM2*i + DIM2*j + k.

– Steve Jessop Jul 5 '11 at 11:38 Oh, and another possible benefit of the memory being fragmented, probably not in this case, is that if DIM1*DIM2 is smaller than the largest available contiguous address range, and DIM1*DIM2*DIM3 is larger than the largest available contiguous address range, then it might turn out to be possible to allocate the memory fragmented, but not in a single block, even though the former requires more memory total. In this case, 144MB is a reasonable single allocation on a PC, and anyway fragmenting all the way down to 64B seems overkill even if this is a potential risk. – Steve Jessop Jul 5 '11 at 11:47.

Defining a multidimensional array as an array of arrays of arrays is very handy, because you can access the elements with the familiar pijk notation, instead of doing index arithmetics. However, others have already pointed out that it is less efficient than allocating the whole array as a big chunk. You can have the best of both worlds with the following trick: allocate an array of dim_len0 pointers to an array of dim_len0*dim_len1 pointers to an array of dim_len0*dim_len1*dim_len2 data cells.

This way you have only three allocations (as many as dimensions) and you can still use the easy pijk notation, provided the intermediate arrays of pointers are properly initialized. And you can also do index arithmetics on **p, at your choice. Here is my version of your program using that trick: /* * Allocation of multidimensional arrays.

*/ #include #include #include #include /* * Allocate a multidimensional array of unsigned chars. * Cast the returned pointer to (unsigned char **...*) */ void *mm(const int dim_len) { int i, j, size, nmemb = 1, prev_nmemb; void *p = NULL, *q = NULL; void **prev_q; for (i = 0; dim_leni; i++) { prev_nmemb = nmemb; nmemb *= dim_leni; size = dim_leni+1? Sizeof(void *) : sizeof(unsigned char); prev_q = q; q = malloc(nmemb * size); if (i == 0) p = q; else for (j = 0; j \n"); p = mm(dims); printf("Filling the array.

\n"); for (i = 0; I \n"); sleep(10); printf("Freeing memory. \n"); ff(p, 3); printf("Waiting 10 seconds. \n"); sleep(10); return 0; } My tests here show that when I free the multidimensional array, memory is actually returned to the OS.

Here is the output of ps just before and just after freeing: USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND edgar 5201 73.0 3.7 151852 150556 pts/0 S+ 14:11 0:00 . /test edgar 5201 6.1 0.0 1668 408 pts/0 S+ 14:11 0:00 . /test.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions