2017-02-13 13 views
0

Я пытаюсь создать временную структуру «итератора», которая назначается началу «списка», а затем перебирает этот список структур, проверяя iterator->next != NULL. Я считаю, что проблема заключается в линиях iterator = start (35 & 70).Ошибка сегментации при назначении struct = struct

Приложение компилируется без каких-либо проблем, но мне дается ошибка сегментации (ядро сбрасывается), когда приложение ./.

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

struct record 
{ 
    int    accountno; 
    char    name[25]; 
    char    address[80]; 
    struct record*  next; 
}; 

int  addRecord (struct record **, int, char [], char []); 
void printAllRecords(struct record *); 

int main(int argc, char *argv[]) { 
    struct record ** start; 
    start = NULL; 

    addRecord(start, 1, "Record Name", "Record Address"); 
    printAllRecords(*start); 

    return 0; 
} 

void printAllRecords(struct record * start) 
{ 
    struct record * recordIterator; 

    /* Allocate the required memory and return a pointer to it */ 
    recordIterator = malloc(sizeof(struct record)); 

    /* Start at the beginning */ 
    recordIterator = start; 

    printf("\n\n%10s %20s %20s\n", "accountno", "Name", "Address"); 

    while (recordIterator != NULL) 
    { 
     printf("%10d %20s %20s\n", recordIterator->accountno, recordIterator->name, recordIterator->address); 
     recordIterator = recordIterator->next; 
    } 
} 

int addRecord (struct record ** start, int accountno, char name[], char address[]) 
{ 
    struct record * newRecord; 

    /* Allocate the required memory and return a pointer to it */ 
    newRecord = malloc(sizeof(struct record)); 

    /* Assign values to the new record */ 
    newRecord->accountno = accountno; 
    strcpy(newRecord->name, name); 
    strcpy(newRecord->address, address); 

    if (start == NULL) 
    { 
     start = &newRecord; 
    } 
    else 
    { 
     struct record * recordIterator; 

     /* Allocate the required memory and return a pointer to it */ 
     recordIterator = malloc(sizeof(struct record)); 

     /* Start at the beginning */ 
     recordIterator = *start; 

     while (recordIterator->next != NULL) 
     { 
      recordIterator = recordIterator->next; 
     } 

     recordIterator->next = newRecord; 
    } 

    return 1; 
} 
+0

'start' в' addRecord' является локальной копией. Это изменение не будет отражено после возвращения функции. –

+1

Почему вы динамически выделяете память только для немедленного выброса? Ваша программа утечки памяти ... bad – StoryTeller

+1

Нет причин, по которым 'start' должен быть указателем на указатель в main. Объявите его как простой указатель, затем передайте его адрес функции. – Lundin

ответ

4

Вы можете объявить start быть указателем, как в

struct record * start;

И тогда вы можете вызвать метод с помощью addRecord(&start, ...).

Внутри метода:

int addRecord (struct record ** start, int accountno, char name[], char address[]) 
{ 
    struct record * newRecord; 

    /* Allocate the required memory and return a pointer to it */ 
    newRecord = malloc(sizeof(struct record)); 

    /* Assign values to the new record */ 
    newRecord->accountno = accountno; 
    strcpy(newRecord->name, name); 
    strcpy(newRecord->address, address); 

    if (*start == NULL) 
    { 
     *start = newRecord; 
    } 

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

+0

В этом была проблема. Наряду с назначением 'struct record ** start' issue в main (изменено на' struct record * start'). – kneeki

2

Эта линия

addRecord(start, 1, "Record Name", "Record Address"); 

не будет изменять start. Поэтому start по-прежнему NULL, когда вы позвоните printAllRecords.