Ошибка сегментации, когда strcpy для struct - PullRequest
0 голосов
/ 03 ноября 2019

У меня есть следующий код:

struct argument {
    char *source;
    char *destination;
    int value;
};

int main(void){
    struct argument *arg2 = malloc(sizeof(struct argument));
    strcpy(arg2->source, "a1"); //This gives segmentation fault.
    strcpy(arg2->destination, "a2");
    arg2->value = 1500;

    return 0;
}

Проблема в том, что когда я использую strcpy с arg2-> destination, все работает нормально, но как только я раскомментирую strcpy с arg2-> source,Я сразу получаю ошибку сегментации. Что случилось? Есть ли способ это исправить?

Ответы [ 2 ]

3 голосов
/ 03 ноября 2019

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

Вам необходимо выделить память для sourceи destination указатели перед их использованием, вы можете использовать malloc(strlen("someString") + 1);. И не не забудьте освободить память, когда закончите, позвонив free. Принятие этой привычки на раннем этапе освободит вас в будущем от некоторых очень неприятных ошибок и еще неопределенного поведения .

1 голос
/ 03 ноября 2019

с этим оператором struct argument *arg2 = malloc(sizeof(struct argument)); вы выделяете память для самой структуры. Структура содержит следующие поля:

struct argument {
    char *source;  // << a pointer to a character string
    char *destination; // << another pointer
    int value; // integer value
};

Далее вы пытаетесь скопировать строку, используя один из указателей: strcpy(arg2->source, "a1");. Но ... в памяти нет места для строки. Вы выделили место для указателя (часть структуры), но не для строки, на которую он будет указывать. Это вызывает повреждение памяти и ваш сбой.

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

arg2->source = malloc(3); 

вам нужно '3', что на 1 символ длиннее, чем длинастрока 'a2'.

такая же для другой строки.

Вам не нужно ничего делать для value. Это не указатель, а часть структуры, которая уже выделена.

...