我正在尝试在C代码中实现动态分配的连续3D数组。数组必须是连续的,因为我依赖于数组的netCDF输出。现在我调整了这里发布的解决方案Stack OverFlow Solution。这适用于动态分配数组并索引它们...但是,当netCDF输出它们时,有一个偏移量,它似乎可以缩放为第二个索引大小(jcount)。这是修改后的功能:
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(第一个索引)的3D指针,构成jret(第二个索引)的2D指针和构成kret的实际值的空间分配空间。然后将2D jret指针与iret的2D阵列部分相关联。然后对于kret也是如此。然后iret的每个地址都指向jret每个部分的第一个值。然后jret的每个地址都指向kret的第一个地址。
对于记录,一切都正常,我的数组的预处理器定义值。另外,如果我在代码中使用一些printf语句来检查数组的数字,它们看起来都正确索引并且代码运行正常,那么输出似乎是数组的非连续内存存储的结果。 / p>
我有一个结构形式:
typedef struct
{
double ***test;
} STRUCT_TYPE;
然后我使用
分配mhd = (STRUCT_TYPE *) malloc(sizeof(STRUCT_TYPE));
mhd.test = (double***) newarray(101,7,101,sizeof(double));
这可能是netCDF的问题......但我只是想知道我的分配例程不是问题。
答案 0 :(得分:1)
这实际上是对Lazer答案中问题的回答:
这让我觉得当C为数组分配内存时,它会分配使用的内存&gt;首先存储值,然后为提供的指针分配内存 结构到多维数组。
也许有人可以为我清除这个?
之间存在非常根本的差异
double arr[A][B][C];
和
double ***ptr;
尽管两者都可以使用x[i][j][k]
编制索引,但生成的机器代码却非常不同。
double arr[A][B][C]
是由C双打的B阵列组成的A阵列。在代码中将此索引编译为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
函数从单个内存块中雕刻出所有这些组件数组,但语言并不需要这样,并且编译器不知道发生这种情况,所以它必须将所有组件阵列视为彼此完全独立。
答案 1 :(得分:0)
嗯,我找到了一个解决方案......虽然它更像是一种惯例。当我最初设计我的代码时,我只是使用预处理器指令来声明我的数组大小。然后我简单地在结构中声明每个数组。为了节省内存,我只是将指向结构的指针传递给了我的子函数。这意味着如果我要引用main()例程之外的元素,我会使用类似的东西:
grid->x;
现在,我引用x的每个元素,如
grid->x[i][j][k];
当然,当netCDF函数需要一个指向它要存储的变量的指针时,我只是传递了它
grid->x
然而,使用这个新的内存分配函数,当我将它传递给一个函数时,我实际上传递了为各种指针留出的内存空间的第一个地址。本质上,我将指针传递给内存中的错误地址。我所要做的就是将传递的参数更改为:
&grid->x[0][0][0]
我得到了正确的数组输出。这让我觉得当C为数组分配内存时,它首先分配用于存储值的内存,然后为指针分配内存,为多维数组提供结构。
也许有人可以为我清除这个?