Инициализация структур в C - предотвращение ошибок сегментации - PullRequest
1 голос
/ 09 марта 2012

Я новичок в C и у меня есть вопрос об инициализации структуры. Я использую структуру, которую я не создал, и поэтому я не знаю, что внутри нее. Поэтому я его не инициализировал, а компилятор пожаловался. Поэтому я установил его равным NULL, но у меня возникла ошибка сегментации. Затем я посмотрел, как установить все в 0, и он сказал, чтобы установить его равным {0}. Это также дало мне ошибку сегментации. Так как я знаю, что функция, которую я вызываю, правильная, и что массив, который я передаю, имеет правильный размер, я почти уверен, что это как-то связано с тем, как я инициализирую структуру. Инициализация

struct aes_ctx *aes_struct = {0}

Заголовок для функции

void aes_setkey(aes_ctx *aes, const void *key, u_int len);

То, как я это называю, это

aes_setkey(aes_struct, aes, CCA_STRENGTH);

где aes - это буфер размера 16, CCA_STRENGTH - это константа int, равная 16.

Чтобы подвести итог проблемы, я думаю, что способ, которым я инициализирую структуру, приводит к тому, что она впоследствии станет непригодной для использования. Любая помощь, которая может быть оказана мне в этом, была бы очень признательна! Спасибо!

Ответы [ 4 ]

5 голосов
/ 09 марта 2012

Вы не можете инициализировать указатель таким образом (ну, вы можете, он просто не указывает на допустимое значение).Что-то вроде этого - то, что вам нужно:

struct aes_ctx aes_struct = {0};

Затем вы можете передать адрес aes_struct функции, но это зависит от того, нужно ли вам динамически выделять эту вещь (требуемая область действия иразмер типа будет диктовать это).

Итак ...

struct aes_ctx aes_struct = {0};
aes_setkey(&aes_struct, aes, CCA_STRENGTH);

Или

struct aes_ctx *aes_struct = malloc(sizeof(struct aes_ctx));
/* you may want to initialize the structure via memset or some init function */
aes_setkey(aes_struct, aes, CCA_STRENGTH);
2 голосов
/ 09 марта 2012

Вы не выделяете память для указателя, чтобы указать.Вы можете использовать либо

struct aes_ctx aes_struct = {0};  // Declare the struct, not a pointer to it
aes_setkey(&aes_struct, aes, CCA_STRENGTH);

, либо, если вы хотите выделить память динамически,

struct aes_ctx *aes_struct = malloc(sizeof(struct aes_ctx));
memset(aes_struct, 0, sizeof(struct aes_ctx); // Only if you need to zero the data
aes_setkey(aes_struct, aes, CCA_STRENGTH);
2 голосов
/ 09 марта 2012

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

struct aes_ctx* aes_struct = malloc(sizeof(struct aes_ctx));

или создайте фактическую структуру (не указатель) и передайте адрес:

struct aes_ctx aes_struct = {0};
aes_setkey(&aes_struct, aes, CCA_STRENGTH);
1 голос
/ 09 марта 2012
struct aes_ctx *aes_struct = {0};

Тем самым вы фактически инициализируете указатель aes_struct на 0.

Две инициализации:

struct aes_ctx *aes_struct = {0};

и

struct aes_ctx *aes_struct = 0;

эквивалентны.C говорит, что вы можете добавить необязательный {} при инициализации скаляра.Таким образом, в основном вы не инициализируете свой указатель на структуру с элементами, инициализированными в ноль, но вы инициализируете указатель с константой нулевого указателя.

Хотя вы можете выполнить первое в одном кадре, используя составные литералы:

struct aes_ctx *aes_struct = (struct aes_ctx) {0};
...