2015-10-30 3 views
0

Я занимаюсь школьным заданием, и я привязался к своей глобальной переменной для связанного списка. Исходя из требований, у меня есть основная функция, которая вызывает функцию loadFile(). Эта функция проверяет, принимает ли вход и токенизирует ее, затем добавляет слова в связанный список. Функция loadFile() вызывает функцию insert(), которая создает узел и добавляет его в список. Эта проблема заключается в том, что список работает отлично, если я печатаю из функции loadFile(), но не работает правильно, если я пытаюсь распечатать из основной функции. У меня есть глава узла как глобальная переменная, но это, похоже, не работает.Глобальный указатель в C не обновляется правильно

Node **headNode = NULL; 
Node **curr = NULL; 

Boolean insert(char *new_string){ 
Node *temp = (Node *)malloc(sizeof(Node)); 
temp->item = new_string; 
if(headNode == NULL){ 
    temp->next = NULL; 
    headNode = &temp; 
} 
else{ 
    temp->next = (*headNode); 
    headNode = &temp; 
} 
return true; 
} 

void loadFile() 
{ 
#define LINE_SIZE 256 
    char input[LINE_SIZE]; 
    char *token = NULL; 

    while (fgets(input, LINE_SIZE, stdin)) 
    { 
    // parse the data into separate elements 
    token = strtok(input, " \t\n"); 
    while (token) 
    { 
     insert(token); 

     token = strtok(NULL, " \t\n"); 
     } 
    } 
} 
+0

Пожалуйста, открепите свой код. – Lundin

ответ

4

Проблема, скорее всего, в строке:

temp->item = new_string; 

new_string является указателем, который является локальным для loadFile. Когда вы вернетесь с loadFile, указатель недействителен.

Замените его

temp->item = strdup(new_string); 

strdup не является стандартной функцией библиотеки, но вы можете реализовать его очень легко. Посмотрите в сети.

+0

Вы сказали, что 'strdup' является _not_ стандартной библиотечной функцией? Как я уверен, вы уже знаете, это часть POSIX 1003.1, поэтому я предполагаю, может быть, вам нужен сон? ;-) –

+2

@CraigEstey: Да, C-стандарт делает * not * define 'strdup()'. – alk

+0

Всегда лучше использовать malloc + memcpy, чем strdup, поскольку первые два являются стандартами C и также быстрее, чем strdup. – Lundin

2

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

headNode = &temp; 

Вы назначаете адрес локальной переменной. Эта переменная выходит из области видимости сразу после возврата из функции и делает недействительным указатель на голову. Если глобальная голова была просто указатель, вы могли бы сделать

headNode = temp; 

и правильно назначить ручку свеже выделенной памяти в вашей голове.

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

void insert(Node **head, const char *item); 

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

Node *head = NULL; 

insert(&head, "banana"); 

В этом случае местный голову от призвания функция изменяется с помощью указателя на указатель узла – в функции insert, head - адрес указателя узла headв функции вызова. Обратите внимание, что голова связанного списка в вызывающем коде все еще только указатель узла.

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

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