2016-10-25 4 views
-3

У меня возникла проблема со следующей программой. Когда я пытаюсь скомпилировать его, он падает. Я предполагаю, что это ошибка сегментации где-то в функции вставки, но я просто не могу понять, где.C реализация malloc struct

char *names[HOW_MANY]= {"Simon", "Suzie", "Alfred", "Chip", "John", "Tim", 
      "Harriet"}; 
int ages[HOW_MANY]= {22, 24, 106, 6, 18, 32, 24}; 

struct person 
{ 
    char name[40]; 
    unsigned int age; 
    struct person *next; 
}; 

struct person* insert(struct person *people[], char *name, int age) 
{ 
    struct person *ptr; 
    ptr=(struct person *)malloc(sizeof(struct person)); 
    if(ptr==NULL) 
    { 
    printf("error"); 
    return; 
    } 
    //ptr=ptr->next; 
    strcpy(ptr->name,name); 
    ptr->age = age; 
    ptr->next=NULL; 

} 

int main() 
{ 
    struct person *people[HOW_MANY]; 
    for (int i =0; i<HOW_MANY;i++) 
     insert (people, names[i], ages[i]); 

    for(int i=0;i<HOW_MANY;i++) 
    printf("%s %d\n", people[i]->name, people[i]->age); 
    return 0; 
} 
+2

Вы выполнили одноэтапный код с помощью отладчика? Это должно сказать вам, какая строка имеет сбой. Я отмечаю, что 'insert' никогда не помещает' ptr' в массив 'people', который, как я предполагаю, является основной проблемой. – cxw

+1

У вас конфликтующие цели в коде. Наличие члена 'next' означает, что вы хотите иметь связанный список людей, но вы объявляете массив указателей' struct person' в 'main()'. Вы пытаетесь построить массив или связанный список людей? – eddiem

+0

массив указателей struct person –

ответ

2

Вот небольшое изменение, которое должно вам двигаться вперед:

void insert(struct person **person_ptr, char *name, int age) 
{      /* ^^^^^^^^^^^^ one person */ 
    struct person *ptr; 
    ... 
    ptr->next=NULL; 
    *person_ptr = ptr; /* send _ptr_ back to the calling code. */ 
} 

int main() 
{ 
    struct person *people[HOW_MANY]; 
    for (int i =0; i<HOW_MANY;i++) 
     insert (&people[i], names[i], ages[i]); 
      /*^ ^^^ Just pass the one person you're interested in */ 
    ... 
} 

Объяснение: **person_ptr берет адрес указателя (&people[i]). Тогда *person_ptr=... изменит это значение. Таким образом, эффект заключается в том, что insert() делает (по существу) *&people[i]=ptr;, то есть people[i]=ptr;. Вам нужны & и *, потому что C передает аргументы по значению, а не по ссылке.

Обратите внимание, что с кодом возникают некоторые другие проблемы.

  • Если у вас закончилась нехватка памяти, вызывающий абонент insert() этого не знает. Вы знаете это из-за распечатки "error", но вызывающий должен это знать.
  • Как указал @eddiem, вам не нужны next, если вы используете только массивы.
  • insert() объявлен как возвращенный struct person*, но это возвращаемое значение никогда не назначается или не используется. insert() может быть void insert() или (указать успех или неудачу) bool insert().
+0

'return (ptr);' было бы намного проще. –

+0

@AndrewHenle Согласен. Я пытался как можно ближе придерживаться логики OP, следовательно, '**'. – cxw

+0

@cxw функция должна либо вернуть значение, либо объявить 'void' return type –

Смежные вопросы