Error in memset() a 3D array

人走茶凉 提交于 2020-01-06 06:01:47

问题


I dynamically allocate a 3D array:

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));

After that I want to initialize this 3D array. The conventional way is:

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

However, if I want to use memset() to initialize the array, it seems unfeasible because the first input is *ptr. So if I write

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

The first input a[0] is a **ptr, which is wrong. If I write:

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

The first input is a *ptr, but there's no n1-dimension any more.

So I'm wondering if memset() can only be used to initialize a 2D matrix?

** I understand memset can't be used on 3D array, but for 2D array I think it's feasible. Here's an example:

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);

This is also not contiguous memory? But it can get correct result.


回答1:


Your "3d array" is not really an array of arrays like memset expects it to be. If we draw it out it will look something like this:

     +------+------+-----+-----------+
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] |
             +------------+------------+-----+-----------------+

This layout is also called jagged arrays. But no matter what it is called, your memset call expects the memory you write to to be contiguous, which your "3D array" isn't.

In short, you can not use memset to initialize your arrays.


There are ways to make it a contiguous memory area, but then you can't really use nice array indexing anymore, but have to use arithmetic to calculate each and every index.




回答2:


memset can only be used to assign a value to a contiguous block of memory - which your 3D array is not. The way you've created it, you create many separate blocks of memory and crucially the chunks that contain the actual values won't be near each other.

You could create the array in one allocation like this

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

and then you could use memset with it and you'd reference into it like this

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


来源:https://stackoverflow.com/questions/50703042/error-in-memset-a-3d-array

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!