C 堆栈内存使用连续动态分配数组与静态分配数组
我使用的是可变大小的3D和4D阵列,它们必须是连续的(有时称为C 堆栈内存使用连续动态分配数组与静态分配数组,c,multidimensional-array,stack,C,Multidimensional Array,Stack,我使用的是可变大小的3D和4D阵列,它们必须是连续的(有时称为*(&x[0][0][0]+k)比“x[][[]”更容易)。”由于数组大小可变,我需要动态分配。我在另一个答案()中找到了这段代码,它工作得很好,但我不知道堆栈使用了多少内存 double***arr3dAlloc(常量int ind1、常量int ind2、常量int ind3){ int i; int j; double***数组=(double***)malloc((ind1*sizeof(double*))+ (ind1*in
*(&x[0][0][0]+k)
比“x[][[]
”更容易)。”由于数组大小可变,我需要动态分配。我在另一个答案()中找到了这段代码,它工作得很好,但我不知道堆栈使用了多少内存
double***arr3dAlloc(常量int ind1、常量int ind2、常量int ind3){
int i;
int j;
double***数组=(double***)malloc((ind1*sizeof(double*))+
(ind1*ind2*sizeof(双**))+
(ind1*ind2*ind3*sizeof(双));
对于(i=0;i
问题是:
double***arr1=arr3dAlloc(N1,N2,N3)之间的区别是什么代码>和
双arr2[N1][N2][N3]代码>
- 假设
使用堆栈的arr2
内存,那么N1*N2*N3*sizeof(double)
使用多少内存?只有arr1
sizeof(双***)
- 一般来说,有没有一种方法可以测量任何变量的堆栈内存使用情况
long
或long
)。该大小和所引用的内存类型无关。(A“**
”只是指另一个指针。)
数组类型[N]总是分配sizeof(type)*N字节的内存sizeof()
包括将类型填充到正确的对齐边界。
因此,使用malloc(sizof(type)*N)
将为类型为N的元素数组分配足够的内存,从而提供指向已分配内存块的指针。您可以使用calloc()
将内存初始化为零
由于分配的内存不依赖于多维数组的组织,因此这种方法适用于任意数量的维度>=1
要回答您的问题:
只是存储指向某个内存区域的指针, 而double***arr1=…
正在为arr2[N1][N2][N3]
双倍分配填充空间N1*N2*N3
使用arr1
字节, 而sizeof(void*)
正在使用arr2
字节N1*N2*n3*sizeof(double)
总是给出变量的大小, 这是在数据/bss段中还是在堆栈上sizeof(var)
long
或long
)。该大小和所引用的内存类型无关。(A“**
”只是指另一个指针。)
数组类型[N]总是分配sizeof(type)*N字节的内存sizeof()
包括将类型填充到正确的对齐边界。
因此,使用malloc(sizof(type)*N)
将为类型为N的元素数组分配足够的内存,从而提供指向已分配内存块的指针。您可以使用calloc()
将内存初始化为零
由于分配的内存不依赖于多维数组的组织,因此这种方法适用于任意数量的维度>=1
要回答您的问题:
只是存储指向某个内存区域的指针, 而double***arr1=…
正在为arr2[N1][N2][N3]
双倍分配填充空间N1*N2*N3
使用arr1
字节, 而sizeof(void*)
正在使用arr2
字节N1*N2*n3*sizeof(double)
总是给出变量的大小, 这是在数据/bss段中还是在堆栈上sizeof(var)
- 这里有几个问题需要解决
第一个是全局变量、堆和堆栈之间的区别。这些都是RAM的所有部分。malloc()分配堆的一部分并返回指针。这在互联网上的许多其他地方都有讨论
另一个问题是编译时与运行时分配。对于编译时分配,必须事先知道数组的大小。您的示例使用运行时分配(
malloc()
),因为数组的大小作为变量传递到函数中。在编译时不知道数组大小的情况下,不可能在堆栈上或全局中分配数组。这里有几个问题需要解决
第一个是全局变量、堆和堆栈之间的区别。这些都是RAM的所有部分。malloc()分配堆的一部分并返回指针。这在互联网上的许多其他地方都有讨论
另一个问题是编译时与运行时分配。对于编译时分配,必须事先知道数组的大小。您的示例使用运行时分配(
malloc()
),因为数组的大小作为变量传递到函数中。在编译时不知道数组大小的情况下,无法在堆栈上或全局中分配数组。您的代码将一个3D数组和一个指针数组分配给指向double
的指针数组,以通过双间接访问其元素。这种方法存在一些问题:
- 您的代码没有将
数组与double
边界对齐。如果指针的大小为4字节且数组的大小为3x4x5,则double
数组将未对齐,这可能会导致未定义的行为double
double ***arr3dAlloc(int ind1, int ind2, int ind3) { size_t level1_size = sizeof(double**) * ind1; size_t level2_size = sizeof(double*) * ind1 * ind2; size_t padding = (sizeof(double) - (level1_size + level2_size) % sizeof(double)) % sizeof(double); size_t level3_size = sizeof(double) * ind1 * ind2 * ind3; int i, j; double ***array = calloc(1, level1_size + level2_size + padding + level3_size); double *array3d = (double*)((unsigned char*)array + level1_size + level2_size + padding); for (i = 0; i < ind1; ++i) { array[i] = (double**)(array + ind1) + i * ind2; for (j = 0; j < ind2; ++j) { array[i][j] = array3d; array3d += ind3; } } return array; }
/* array3d is a pointer to an allocated 3D array: */ double (*array3d)[ind2][ind3] = calloc(sizeof(*array3d), ind1); /* array3d can be used like a statically defined array: */ for (int i = 0; i < ind1; i++) { for (int j = 0; j < ind2; j++) { for (int k = 0; k < ind3; k++) { array3d[i][j][k] = i + j + k; } } }