简体   繁体   English

二维数组的动态内存分配

[英]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???在这段代码中,当我们为 2D 数组动态分配内存时,在 4 个地址之后为什么它占用了 16 个字节的间隙,但是当我们静态分配 2D 数组时它没有这样的间隙......这是什么原因这背后???

#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).您正在分配一组一维数组,并且这些分配不必是连续的(大多数malloc实现保留一些字节来存储已分配块的大小)。

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.严格来说,这种行为是未定义的——因为arr指向一个 VLA,所以sizeof *arr表达式必须在运行时计算,而不是在编译时,并且arr在那个点不是有效的指针值。 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如果c是常量,比如

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.那么就不会有问题,这将是动态分配 Nx3 数组的首选方式。

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如果您想要 2D 表示法的便利,您可以尝试创建一个指针并设置为指向数组的开头,例如

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 .但是如果指针类型不兼容,这种指针别名也是未定义的,我们没有理由期望指向T的指针与指向T数组的指针兼容。

The comments on your question have the most essential advice - don't worry about where malloc puts your memory.关于你的问题的评论有最重要的建议 - 不要担心 malloc 把你的记忆放在哪里。 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.如果不出意外,您对 malloc 的调用之间的其他内存分配、对 free 的调用、垃圾收集(在具有 GC 的语言中,即)将影响下一次分配的位置。

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.至于您的分配有 16 字节差距的具体原因,如果没有更多,并且可能非常深入地了解您的场景,就不可能说出来。 BTW, you didn't include output of your printf in your question.顺便说一句,您没有在问题中包含printf输出。

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.但是如果我不得不猜测,我会说内存管理器正在将分配与内存边界对齐……可能是 32 字节或 64 字节的边界。

You're allocating 4 * sizeof(int) .您正在分配4 * sizeof(int) If an int is 4 bytes on your system, that's 16 bytes.如果系统上的 int 为 4 个字节,则为 16 个字节。 If your malloc likes to line things up to 32 bytes, that might explain the 16-byte gaps you're seeing.如果您的malloc喜欢将最多 32 字节的内容排成一行,这可能解释了您看到的 16 字节间隙。

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. malloc更大的内存块,然后在内部管理您自己的指针和分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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