我试图在C代码中实现动态分配的连续3D数组。数组必须是连续的,因为我依赖数组的netCDF输出。现在我修改了一个发布在这里的解决方案。这很好地用于动态分配数组和索引它们…但是,当NETCDF输出它们时,出现了一个偏移,其偏移量作为第二索引大小(JCUT)。下面是修改后的函数:
void*** newarray(int icount, int jcount, int kcount, int type_size)
{
int i,j,k;
void*** iret = (void***)malloc(icount*sizeof(void***)+icount*jcount*sizeof(void**)+icount*jcount*kcount*type_size);
void** jret = (void**)(iret+icount);
char* kret = (char*)(jret+icount*jcount);
for(i=0;i<icount;i++)
{
iret[i] = &jret[i*jcount];
}
for(i=0;i<icount;i++)
{
for(j=0;j<jcount;j++)
{
jret[i*jcount+j] = &kret[i*jcount*kcount*type_size+j*kcount*type_size];
}
}
return iret;
}
如果我正确理解这个函数,iret被分配给组成iret的3D指针(第一个索引)、组成jret的2D指针(第二个索引)和组成kret的实际值的空间。然后,2djret指针与iret的2D数组部分相关联。对克雷特也是如此。然后iret的每个地址都指向jret每个部分的第一个值。然后,jret的每个地址都指向kret的第一个地址。
据记录,我的数组的预处理器定义值一切正常。另外,如果我在代码中使用一些printf语句来检查数组的数字,它们看起来都索引正确,并且代码运行正确,那么输出似乎是数组的非连续内存存储的结果。
我有一个表格结构:
typedef struct
{
double ***test;
} STRUCT_TYPE;
然后我使用
mhd = (STRUCT_TYPE *) malloc(sizeof(STRUCT_TYPE));
mhd.test = (double***) newarray(101,7,101,sizeof(double));
这可能是netCDF的问题…但我想知道我的分配例程不是问题所在。
最佳答案
这实际上是对拉泽回答中问题的回答:
这使我认为,当C为数组分配内存时,它首先分配用于存储值的>内存,然后为提供
多维数组的结构。
也许有人能帮我清理一下这个?
在C中有一个非常基本的区别
double arr[A][B][C];
和
double ***ptr;
尽管两者都可以用
x[i][j][k]
进行索引,但生成的机器代码是非常不同的。double arr[A][B][C]
是一个A数组,B数组,C double数组。当在代码中将此索引为arr[i][j][k]
时,编译器从((i*B + j)*C + k)*sizeof(double)
的开始将其转换为arr
字节的偏移量。这里不涉及中间指针,但是编译器必须知道维度B和C。“double***ptr”是指向指向double的指针(数组的开始)的指针(数组的开始)。当在代码中将此索引为
ptr[i][j][k]
时,编译器别无选择,只能独立地执行每个索引操作,并遵循所有中间指针。这导致代码类似于temp1 = ptr[i];
temp2 = temp1[j];
result = temp2[k];
newarray
函数将所有这些组件数组从一个内存块中划出,但这不是语言所需要的,编译器不知道这是在发生的,因此它必须将所有组件数组视为彼此完全独立。关于c - C中的动态连续3D阵列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4016842/