简体   繁体   中英

Dynamic memory allocation of 2d array

In this code, while we are dynamically allocating memory for the 2D array, after 4 address why it is taking a gap of 16 bytes but when we are statically allocating 2D array then it does not have such gap.... what is the reason behind this???

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    int r = 3, c = 4, i, j, count; 

    int stat[r][c];

    int *arr[r]; 
    for (i=0; i<r; i++) 
         arr[i] = (int *)malloc(c * sizeof(int)); 

    // Note that arr[i][j] is same as *(*(arr+i)+j) 
    count = 0; 
    for (i = 0; i <  r; i++) 
      for (j = 0; j < c; j++) 
         arr[i][j] = ++count; // Or *(*(arr+i)+j) = ++count 

    for (i = 0; i <  r; i++) 
      for (j = 0; j < c; j++) 
         printf("%d\n", *(arr+i)+j); 

    printf("\n\n");  
    for (i = 0; i <  r; i++) 
      for (j = 0; j < c; j++) 
         printf("%d\n", *(stat+i)+j); 

    /* Code for further processing and free the  
      dynamically allocated memory */

   return 0; 
} 

Because you are not allocating a 2D array. You are allocating a set of 1D arrays, and those allocations do not have to be contiguous (most malloc implementations reserve some bytes to store the size of the allocated block).

To dynamically allocate a "true" 2D array where number of rows and columns aren't known until runtime, you'd do something like this:

stat (*arr)[c] = malloc( sizeof *arr * r );

that would be contiguous like any "normal" 2D array.

But...

Strictly speaking, this behavior is undefined - since arr points to a VLA, the sizeof *arr expression must be evaluated at runtime , not at compile time, and arr is not a valid pointer value at that point. I've never seen this fail on any implementation I've used, but that doesn't mean it won't fail somewhere. If c were constant instead, like

stat (*arr)[3] = malloc( sizeof *arr * r );

then there wouldn't be a problem, and this would be the preferred way to dynamically allocate an Nx3 array.

If you need all array elements to be contiguous (such that you could traverse the entire array with a pointer or something like that), then the safest option is to allocate your memory as a 1D array:

stat *arr = malloc( sizeof *arr * r * c );

and compute the offsets manually:

x = arr[ i * r + j ];

If you want the convenience of 2D notation, you could try creating a pointer and setting to point to the beginning of the array, something like

stat (*ptr)[c] = (stat (*)[c]) arr;

but that kind of pointer aliasing is also undefined if the pointer types are not compatible, and we've no reason to expect that a pointer to T is compatible with a pointer to an array of T .

The comments on your question have the most essential advice - don't worry about where malloc puts your memory. There is no assurance that it will be in any order. It may locate allocations in pursuit of various optimizations or speculations, and may vary from one execution to the next. If nothing else, other memory allocations, calls to free, garbage collection (in languages with GC, that is) between your calls to malloc will affect the location of the next allocation.

This can also vary with compiler, compiler options, OS, etc.

As for the specific reason your allocations have a 16 byte gap, that's impossible to say without more, and likely very deep, insight into your scenario. BTW, you didn't include output of your printf in your question.

But if I had to guess, I'd say the memory manager was aligning the allocations up with memory boundaries...perhaps a 32-byte or 64-byte boundary.

You're allocating 4 * sizeof(int) . If an int is 4 bytes on your system, that's 16 bytes. If your malloc likes to line things up to 32 bytes, that might explain the 16-byte gaps you're seeing.

But again...this is just a guess. The simple answer is...you shouldn't care.

But if you DO care for some reason, you probably need to do your own allocation. malloc a much larger chunk of memory, and then manage your own pointers and allocations internally.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM