链接列表数据全部相同
我正在尝试从.txt文件中读取输入,并将其添加到单个链接列表中。 我遇到的问题是正在创建节点并正确连接(我得到了正确的长度),但在添加所有节点后,每个数据字段都是相同的。 我想知道问题是什么,以及如何解决它。 已经有一段时间了!
添加function:
#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); }
您的代码中的错误是:在processFile()函数中调用free(input)
并访问空闲内存导致运行时出现“未定义行为”时,地址分配给newNode->Data->FName
变为无效。
要更正您的代码:
而不是简单的任务,如:
newNode->Data->FName = strtok(input," ");
在单独的内存中分配和复制如下:
char *ptr = strtok(input," "); newNode->Data->FName = malloc(strlen(ptr)+1); strcpy(newNode->Data->FName, ptr);
实际上你是在addOrdered()中从input
地址空间分配内存地址,并在processFile()
函数中使free()
。
我在下面详细解释您的代码:
首先阅读: 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
地址scape。
同样在你的代码中,分配给newNode->Data->FName = strtok(input," ");
在addOrdered()
函数中。 newNode->Data->FName
内存地址值是in / from你最后在processFile()
函数中释放的input
所以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"
其次 ,你应该从缓冲区中的文件中读取少一个char,为null \0
保留空间。
fgets(input, SIZE-1, fd)
strtok返回指向string中找到的最后一个标记的指针。 如果没有要检索的标记,则返回空指针。 你需要做一些像pch = strtok(input," ");