2013-02-14 3 views
1

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

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

struct Abc { 
    int test; 
    struct Abc *next; 
}; 

void demo_fill(struct Abc *data); 

int main(int argc, char **argv) { 
    struct Abc *db = NULL; 
    demo_fill(db); 
    printf("%d\n",db->test); 
    return 0; 
} 

void demo_fill(struct Abc *data) { 
    int i; 
    for(i = 0; i < 5; i++) { 
     struct Abc *new; 
     new = malloc(sizeof(struct Abc)); 
     new->test = i; 
     new->next = data; 
     data = new; 
    } 
} 

При запуске это «ошибки сегментации (ядро сбрасывали)» ошибка происходит потому, что структура все еще NULL, когда я пытаюсь напечатать первый элемент. Что я делаю не так?

+1

Вы не работаете в отладчике перед отправкой в ​​SO, это то, что вы делаете неправильно. – djechlin

ответ

5

Вы передаете указатель по значению. Вам нужно передать указатель на указатель, если вы хотите изменить значение указателя вызывающего абонента:

int main(int argc, char **argv) { 
    struct Abc *db = NULL; 
    demo_fill(&db); 
    printf("%d\n",db->test); 
    return 0; 
} 

void demo_fill(struct Abc **data) { 
    int i; 
    for(i = 0; i < 5; i++) { 
     struct Abc *new; 
     new = malloc(sizeof(struct Abc)); 
     new->test = i; 
     new->next = *data; 
     *data = new; 
    } 
} 
2

Назначение данных на новый не будет иметь никакого эффекта. data - это локальная копия указателя. Передайте двойной указатель, чтобы исправить это. Что-то вроде этого:

void demo_fill(struct Abc** data) { 
    int i; 
    for(i = 0; i < 5; i++) { 
     struct Abc *new; 
     new = malloc(sizeof(struct Abc)); 
     new->test = i; 
     new->next = *data; 
     *data = new; 
    } 
} 

И, конечно, вам придется па указатель на БД в основной:

demo_fill(&db) 
+0

Спасибо, что работает. Но все-таки я получаю предупреждение от компилятора: test.c: 24: 15: предупреждение: назначение из несовместимого типа указателя [включено по умолчанию] - это 'new-> next = data;' в цикле – user1163278

+0

Эта строка неверна - она ​​должна быть 'new-> next = * data;' – simonc

+0

Спасибо человеку. Вы решили мою проблему. Пометка как ответ через 9 минут. – user1163278

1

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

struct link { 
    int test; 
    struct link* next; 
}; 
struct list { 
    struct link* first; 
}; 

void demo_fill(struct list* data); 

Затем вы можете изменить первую запись в списке, не думая о синтаксисе **.

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