memset()中出现错误的3D数组

时间:2018-06-05 14:51:35

标签: c memset

我动态分配3D数组:

int n1=2,n2=5,n3=3;
int in1,in2,in3;
float ***a;
a = (float ***)malloc(n1*sizeof(float **));
for (in1=0;in1<n1;in1++)
    a[in1] = (float **)malloc(n2*sizeof(float *));
for (in1=0;in1<n1;in1++)
    for (in2=0;in2<n2;in2++)
        a[in1][in2] = (float *)malloc(n3*sizeof(float));

之后我想初始化这个3D数组。传统方式是:

for (in1=0; in1<n1; in1++)            
    for (in2=0; in2<n2; in2++)      
        for (in3=0; in3<n3; in3++)  
            a[in1][in2][in3] = 1.0f;

但是,如果我想使用memset()来初始化数组,那么它似乎不可行,因为第一个输入是* ptr。所以,如果我写

memset(a[0],1,n1*n2*n3*sizeof(float));

第一个输入a [0]是** ptr,这是错误的。 如果我写:

memset(a[0][0],1,n2*n3*sizeof(float));

第一个输入是* ptr,但不再有n1维。

所以我想知道memset()是否只能用于初始化2D矩阵?

**我理解memset不能用于3D阵列,但对于2D阵列我觉得它是可行的。这是一个例子:

int n1=2,n2=5;
int in1,in2;
float **a;
a = (float **)malloc(n1*sizeof(float *));
for (in1=0;in1<n1;in1++)
    a[in1] = (float *)malloc(n2*sizeof(float));
memset(a[0],0,n1*n2*sizeof(float));
free(*a);free(a);

这也不是连续的记忆?但它可以得到正确的结果。

2 个答案:

答案 0 :(得分:3)

你的“3d数组”实际上不是像memset那样的数组数组。如果我们把它画出来,它将看起来像这样:

     +------+------+-----+-----------+
a -> | a[0] | a[1] | ... | a[n1 - 1] |
     +------+------+-----+-----------+
             |
             v
             +---------+---------+-----+--------------+
             | a[1][0] | a[1][1] | ... | a[1][n2 - 1] |
             +---------+---------+-----+--------------+
              |
              v
             +------------+------------+-----+-----------------+
             | a[1][0][0] | a[1][0][1] | ... | a[1][0][n3 - 1] |
             +------------+------------+-----+-----------------+

此布局也称为锯齿状数组。但不管它叫什么,你的memset调用都希望你写的内存是连续的,你的“3D数组”不是

简而言之,您无法使用memset初始化数组。

方法使它成为一个连续的内存区域,但是你不能真正使用好的数组索引,但必须使用算术来计算每个索引。

答案 1 :(得分:1)

memset只能用于为连续的内存块分配值 - 您的3D数组不是。你创建它的方式,你创建了许多单独的内存块,关键的是包含实际值的块不会彼此靠近。

您可以在一个分配中创建数组,如此

float *big_chunk=malloc(sizeof(float)*n1*n2*n3);

然后您可以使用memset,并且您可以像这样引用它

big_chunk[x*n1+y*n2+z]=some_value;