Intereting Posts
Есть ли документ, описывающий, как Clang обрабатывает избыточную точность с плавающей запятой? Как я могу узнать, какой тип информации об отладке находится в объектном файле ELF? Невозможно передать сгенерированные значения из цикла for в структуру Как рассчитать время рассвета / сумерек Ввод динамического размера с использованием fgets в C Как установить кросс-компилятор gcc Bubble сортировать в c связанном списке Поддерживает ли #ifdef (или другие директивы препроцессора) работу над декларациями функций (для проверки существования функции)? Существуют ли условия гонки в этой реализации производителя-потребителя? Разделите число на 5 без использования оператора разделения Насколько переносимым является код с оптимизацией #pragma? Рекурсивно удалить каталог с помощью C Разделите целое число со знаком на 2 Временная метка препроцессора Найти IP-адрес машины в C?

Данные связанного списка Все одинаковые

Я пытаюсь прочитать входные данные из TXT-файла и добавить его в отдельный список. Проблема, с которой я сталкиваюсь, заключается в том, что узлы создаются и подключаются правильно (я получаю правильную длину), но после добавления всего Узла каждое поле данных одинаково. Мне было интересно, в чем проблема, и как это исправить. Некоторое время приходил на это!

Добавить функцию:

#include "linkedList.h" #include  #include  void addOrdered(Node ** Head,char * input) { printf("\nInput: %s\n",input); Node * cur = (*Head); Node * newNode = malloc(sizeof(Node)); newNode->Data = malloc(sizeof(Person)); newNode->Data->FName = strtok(input," "); newNode->Data->LName = "test"; newNode->Data->id = 5; newNode->Next = NULL; if(cur == NULL) { (*Head) = newNode; } else { for(;cur->Next != NULL;cur = cur->Next) { printf(" Cur->Next "); } cur->Next = newNode; } } 

Файл обработки:

 void processFile(Node ** Head, FILE * fd) { char * input = malloc(sizeof(char)*SIZE); while(fgets(input,SIZE,fd) != NULL) { addOrdered(Head,input); } free(input); } 

Ошибка в вашем коде: newNode->Data->FName адреса newNode->Data->FName становится недействительным после того, как вы вызываете free(input) в функции processFile (), и доступ к свободной памяти вызывает «Undefined Behavior» во время выполнения.

Чтобы исправить код:

вместо простого назначения:

 newNode->Data->FName = strtok(input," "); 

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

 char *ptr = strtok(input," "); newNode->Data->FName = malloc(strlen(ptr)+1); strcpy(newNode->Data->FName, ptr); 

Фактически вы назначали адрес памяти из адресного пространства input в addOrdered () и выполняете функцию free() в функции processFile() .

Я объясню ваш код следующим образом:

Сначала читайте: char * strtok (char * str, const char * delimiters); руководство:

При первом вызове функция ожидает строку C в качестве аргумента для str, первый символ которой используется в качестве исходного места для сканирования токенов. В последующих вызовах функция ожидает нулевой указатель и использует позицию сразу после окончания последнего токена в качестве нового начального местоположения для сканирования.

Возвращаемое значение

Указатель на последний токен, найденный в строке. Возвращает нулевой указатель, если для возврата нет токенов.

Он не отправляет новую память, а память из input которую вы недавно освободили (). Чтобы понять работу strtok (), я написал следующий код:

 int main (){ char str[] ="- This, a sample string."; printf("str address: %p, ends on: %p \n", str, str+strlen(str)); printf ("Splitting string \"%s\" into tokens:\n",str); char * pch; pch = strtok (str," ,.-"); while (pch != NULL){ printf ("pch: %7s, address: %p\n",pch, pch); pch = strtok (NULL, " ,.-"); } return 0; } 

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

 ~$ ./a.out str address: 0x7fff96958d50, ends on: 0x7fff96958d68 Splitting string "- This, a sample string." into tokens: pch: This, address: 0x7fff96958d52 pch: a, address: 0x7fff96958d58 pch: sample, address: 0x7fff96958d5a pch: string, address: 0x7fff96958d61 

Примечание: адрес pch находится из / внутри str адреса.

Аналогично в вашем коде назначьте newNode->Data->FName = strtok(input," "); в функции addOrdered() . значение адреса памяти в newNode->Data->FName находится в / из input который вы в последствии освобождаете в функции processFile() Таким образом, newNode->Data->FName становится недействительным, а ваш код работает как неопределенное поведение

 void addOrdered(Node ** Head,char * input){ printf("\nInput: %s\n",input); // some code here step-2 newNode->Data->FName = strtok(input," "); <--"assign memory" ^ // Some code here | } | | void processFile(Node ** Head, FILE * fd){ | step-1 char * input = malloc(sizeof(char)*SIZE); <-|----"Allocate memory" while(fgets(input,SIZE,fd) != NULL){ | addOrdered(Head,input); ----------------- } step-3 free(input); <-----------------------------------"Free memory" } So, "What is assign to newNode->Data->FName becomes invalid" 

Во-вторых , вы должны прочитать один меньше символов из файла в буфере, сохранить место для null \0 .

 fgets(input, SIZE-1, fd) 

strtok возвращает указатель на последний токен, найденный в строке. Возвращает нулевой указатель, если для возврата нет токенов. Вам нужно сделать что-то вроде pch = strtok(input," ");