Ошибка в memset () трехмерного массива - PullRequest
0 голосов
/ 05 июня 2018

Я динамически выделяю 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 нельзя использовать на трехмерном массиве, но для 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 голосов
/ 05 июня 2018

memset можно использовать только для присвоения значения непрерывному блоку памяти, которым не является ваш 3D-массив.То, как вы его создали, вы создаете много отдельных блоков памяти, и, что особенно важно, куски, которые содержат фактические значения, не будут находиться рядом друг с другом.

Вы можете создать массив в одном выделении, как это

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

и затем вы можете использовать memset с ним, и вы будете ссылаться на него, как это

big_chunk[x*n1+y*n2+z]=some_value;
0 голосов
/ 05 июня 2018

Ваш "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 вызов ожидает, что память, в которую вы записываете, будет смежной, а ваш «трехмерный массив» не .

Короче говоря, вы можетене используйте memset для инициализации ваших массивов.


Есть способы сделать это непрерывной областью памяти, но тогда вы больше не сможете использовать красивую индексацию массива, нонеобходимо использовать арифметику для расчета каждого индекса.

...