выделение памяти указателю на массив структур - PullRequest
0 голосов
/ 06 мая 2020

Я пытаюсь выделить память для указателя на массив структур, но когда я компилирую, терминал отправляет мне ошибку сегментации , это мой код:

typedef struct codif {
    unsigned char simbolo;
    int nbits;
    unsigned int codigo;
} codificacion;

codificacion **matcod;
*matcod = malloc(256 * sizeof((*matcod)[0]));

Ответы [ 3 ]

1 голос
/ 06 мая 2020

Этот указатель

codificacion **matcod;

неинициализирован и имеет неопределенное значение. Таким образом, разыменование его типа *matcod приводит к неопределенному поведению.

Возможно, вы имеете в виду следующее

codificacion *matcod;
matcod = malloc( 256 * sizeof( *matcod ) );

Или что-то вроде следующего

codificacion *p;
codificacion **matcod = &p;
*matcod=malloc(256*sizeof((*matcod)[0]));

Например, если вы иметь функцию, определенную как

void f( codificacion **matcod )
{
    *matcod=malloc(256*sizeof((*matcod)[0]));
    //...
}

, тогда ее можно вызвать как

codificacion *matcod;
f( &matcod );
0 голосов
/ 07 мая 2020

Вы всегда должны чем-то объявлять свои переменные. Компиляторы не всегда обнуляют неинициализированные переменные. Я также большой поклонник использования calloc при объявлении массивов - это стилистический выбор c, но особенно с массивами указателей, он гарантирует, что все обнулено. Отладка неинициализированных данных может быть адом.

codificacion **matcod = NULL;
matcod = calloc(256, sizeof(codificacion*));

Обратите внимание, что мы создали массив указателей из 256 элементов, а не целые структуры, и потому что ** - это массив указателей на структуры, а не массив структуры, которые вам затем нужно выделить для каждой структуры:

for(int index=0; index<256; index++)
  matcod[index] = malloc(sizeof(codificacion));

Затем вы должны ссылаться на свои элементы с помощью matcod[index]->nbits.

Теперь вам нужно просто реализовать плоский массив структур и затем передайте указатель на это. Используя распределение stati c, вы даже можете избежать вызова calloc.

codificacion matcod_array[256] = { 0 };
codificacion *matcod = (codificacion *)&matcod_array;

Поскольку вы передаете только указатель на массив структур, а не на указатель на массив указателей для одиночных структур вы затем должны ссылаться на элементы в массиве, используя matcod[index].nbits.

0 голосов
/ 06 мая 2020

Ожидается, что вы напишете функцию, которая принимает указатель на указатель на этот массив структур в качестве аргумента. Итак, codificacion **matcod - это аргумент функции, а не локальная неопределенная переменная, которая вызывает неопределенное поведение, когда вы разыменовываете ее для сохранения адреса выделенного массива.

Вот модифицированная версия:

typedef struct codif {
    unsigned char simbolo;
    int nbits;
    unsigned int codigo;
} codificacion;

int allocate_array(codificacion **matcod) {
    *matcod = malloc(256 * sizeof((*matcod)[0]));
    return *matcod != NULL;
}

И вызовите эту функцию, передав адрес фактического указателя:

    codificacion *mat;
    if (!allocate_array(&mat)) {
        printf("allocation error\n");
    }
...