Ошибка сегментации в strcpy()

У меня есть базовая структура, как это

typedef struct struck {
    char* id;
    char* mat;
    int value;
    char* place;
} *Truck;

И такая функция, которая создает новый «экземпляр» этой структуры:

Truck CTruck(char* id, char* mat, int value, char* place) {
    Truck nT = (Truck) malloc(sizeof (Truck));
    nT->value = value;
    strcpy(nT->id, id);
    strcpy(nT->mat, mat);
    strcpy(nT->place, place);
    return nT;
}

Я получаю сообщение об ошибке в первом strcpy. Компилируется без проблем.


person MrFabio    schedule 13.04.2012    source источник


Ответы (3)


Ваш typedef определяет Truck как struct struck *, то есть указатель. Таким образом, его размер будет 4 или 8 в зависимости от архитектуры, а не от размера структуры.

Используйте sizeof(*Truck), чтобы получить фактический размер структуры.

Также нужно выделить память для персонажей. Самый простой способ - использовать strdup().

Truck CTruck(const char* id, const char* mat, int value, const char* place) {
    Truck nT = malloc(sizeof (*Truck));
    nT->value = value;
    nT->id = strdup(id);
    nT->mat = strdup(mat);
    nT->place = strdup(place);
    return nT;
}

Однако я бы предложил изменить ваш typedef, чтобы он был псевдонимом для структуры, а не для указателя на нее:

typedef struct {
    char* id;
    char* mat;
    int value;
    char* place;
} Truck;

В вашей функции вы затем используете это:

Truck *nT = malloc(sizeof(Truck));
person ThiefMaster    schedule 13.04.2012
comment
+1 А также malloc немного места для id, mat и place, чтобы strcpy не стирал случайную память. - person JeremyP; 13.04.2012
comment
strdup фут; не нужно использовать malloc и этот противный strcpy - person ThiefMaster; 13.04.2012
comment
У меня есть больше структур, использующих *Stuff в конце typedef, и если я изменю это на }Truck, это даст ошибки на каждой из них, и это malloc(sizeof(Truck)) не будет работать, если я использую *Truck - person MrFabio; 13.04.2012
comment
Хорошо, я думаю, проблема была также в использовании strcpy, я не знал, что strdup, спасибо всем - person MrFabio; 13.04.2012
comment
+1 за указание человеку использовать typedef в качестве псевдонима для struct - person Ed Heal; 13.04.2012

nT->id - это просто указатель. Нужно malloc памяти для копирования строки. То же самое для других.

person Ed Heal    schedule 13.04.2012

Вы неправильно используете sizeof. В общем, аргумент malloc() должен быть «размером того, на что указывает возвращаемый указатель». Другими словами, вам нужно sizeof *nT. Видите, как это также устраняет повторение имени типа (Truck)?

Кроме того, в C вам не нужно приводить возвращаемое значение из malloc(); это бесполезно, может скрыть настоящую ошибку и затрудняет чтение кода.

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

person unwind    schedule 13.04.2012