почему эта простая функция strcpy() вызывает ошибку сегментации?

Я не понимаю что-то простое.

У меня есть этот пример кода:

typedef struct {
  char* fname;
} PersonType;

int main() {
  PersonType *p;
  p  = (PersonType *)malloc(sizeof(PersonType));
  char * name = "Robert";

  /* this next line causes a segmentation fault */  
  strcpy(p->fname, name);

  printf("name: %s\n", p->fname);

}

Почему возникает ошибка сегментации в «strcpy»? Что я делаю неправильно?

Любая помощь очень ценится, спасибо!

Роб


person Community    schedule 12.11.2013    source источник
comment
Вам нужно выделить место для fname; ваш malloc выделяет место только для самого указателя.   -  person Joe    schedule 12.11.2013
comment
Вам также необходимо выделить память для fname. Выделения памяти только для PersonType недостаточно.   -  person benipalj    schedule 12.11.2013


Ответы (3)


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

int main() {
   PersonType *p;
   p  = (PersonType *)malloc(sizeof(PersonType));
   p->fname = malloc(sizeof(char)*7);
   char * name = "Robert";

Либо так, либо сделайте fname массивом char, чтобы ваша структура содержала внутри себя буфер.

person shf301    schedule 12.11.2013

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

if (p != 0)
{
    if ((p->fname = malloc(strlen(name) + 1)) != 0)
        strcpy(p->fname, name);
    else
        free(p);  // Report error too?
}

Обратите внимание, что это проверяет результаты выделения памяти. Меня не волнует, приводите ли вы возвращаемый тип для malloc(); другие люди.

person Jonathan Leffler    schedule 12.11.2013

fname ничем не инициализирован. strcpy продолжит чтение, начиная с места, на которое указывает fname, пока не встретит \0.

Либо сделайте fname массивом, и инициализируйте его. Или выделите fname и инициализируйте его.

person Paul Draper    schedule 12.11.2013