链表数据都是一样的 [英] Linked List Data All The Same
问题描述
我想从一个.txt文件中输入读取数据,并将其添加到一个单链表。我遇到的问题是正在创建和连接正确(我得到正确的长度)节点,但将所有的节点后,每个数据字段是相同的。我想知道是什么问题,以及如何解决它。它已经持续一段时间了!
添加功能:
的#includelinkedList.h
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;无效addOrdered(节点**头,字符*输入)
{ 的printf(\\ nInput:%S \\ n,输入); 节点* CUR =(*头); 节点* newNode =的malloc(sizeof运算(节点));
newNode->数据=的malloc(sizeof的(人)); newNode->数据 - > FName参数= strtok的(输入,);
newNode->数据 - > LName的=测试;
newNode->数据 - > n = 5;
newNode->接着= NULL; 如果(当前== NULL)
{
(*头)= newNode;
}
其他
{ 为(;电流>!接着= NULL; CUR =电流>接着)
{
输出(当前>接下来);
} 当前>接下来= newNode;
}
}
处理文件:
无效processFile(节点**头,FILE * FD)
{
字符*输入=的malloc(sizeof的(char)的* SIZE); 而(与fgets(输入,大小,FD)!= NULL)
{
addOrdered(头,输入);
}
免费(输入);
}
在code中的错误是:地址分配给 newNode->数据 - > FName参数
一旦你叫免费(输入)
在processFile()函数,并使用免费的内存会导致在运行时未定义行为变为无效。
要纠正你的code:
而不是简单的赋值一样的:
newNode->数据 - > FName参数= strtok的(输入,);
分配,并在下面单独的内存复制:
的char * PTR = strtok的(输入,);
newNode->数据 - > FName参数=的malloc(strlen的(PTR)+1);
的strcpy(newNode->数据 - > FName参数,PTR);
其实你是从输入
在addOrdered地址空间(),使免费()
在<分配的内存地址code> processFile()功能。
我解释一下你的code以下精心方式:
首先阅读:的char * strtok的(字符*海峡,为const char *分隔符); 一>手动:
在第一次呼叫,该函数需要一个C字符串作为论据海峡,其第一个字符作为起始位置扫描令牌。在随后的电话,该函数需要一个空指针和使用位置最后一个令牌作为扫描新的起点位置结束后的权利。
返回值
一个指向字符串中找到的最后一个令牌。
如果没有留下标记检索,则返回一个空指针。
块引用>它的不会从
输入发送新的内存
的内存,但你最近免费的()。要理解的strtok()函数的工作,我写如下code:INT的main(){
烧焦海峡[] = - 这,样本串;
的printf(海峡地址:%P,结束于:%P \\ N,STR,STR +的strlen(STR));
的printf(分割字符串\\%s \\的成标记:\\ n,STR);
字符* PCH;
PCH = strtok的(STR,.-);
而(PCH!= NULL){
的printf(PCH:%7S,地址:%P \\ N,PCH,PCH);
PCH =的strtok(NULL,.-);
}
返回0;
}以上程序的执行(的地址可以是在每次运行不同的的):
〜$ ./a.out
STR地址:0x7fff96958d50,结束于:0x7fff96958d68
分割字符串 - 这,样本串。成标记:
PCH:这,地址:0x7fff96958d52
PCH:一,地址:0x7fff96958d58
PCH:样本,地址:0x7fff96958d5a
PCH:字符串,地址:0x7fff96958d61注意:
PCH
地址是从/在STR
地址景观的同样在code,分配给
newNode-&GT;数据 - &GT; FName参数= strtok的(输入,);
在addOrdered()
功能。数据 - &GT; FName参数在/从输入
您在近来免费<在newNode-&GT内存地址值code> processFile()
函数,所以newNode-&GT;数据 - &GT; FName参数
变得无效和你的code运行为未定义行为无效addOrdered(节点**头,字符*输入){ 的printf(\\ nInput:%S \\ n,输入);
//一些code在这里
第2步
newNode-&GT;数据 - &GT; FName参数= strtok的(输入,); &LT; - 分配内存
^
//有些code这里|
} |
|
无效processFile(节点**头,FILE * FD){|步骤1
字符*输入=的malloc(sizeof的(char)的* SIZE); &LT; - | - 分配内存
而(与fgets(输入,大小,FD)!= NULL){|
addOrdered(头,输入); -----------------
} STEP-3
免费(输入); &LT; -----------------------------------空闲内存
}那么,什么是分配给newNode-&GT;数据 - &GT; FName参数无效二,你应该阅读从缓冲区的文件少了一个字符,保持空间空
\\ 0
。与fgets(输入,1型尺寸,FD)
I'm trying to read in input from a .txt file, and add it into a singly linkedlist. The problem I'm having is the Nodes are being created and connected correctly (I'm getting the correct length), but after adding all the Node, each Data field is the same. I was wondering what the problem is, and how to fix it. Been going at it for awhile!
Add Function:
#include "linkedList.h" #include <stdlib.h> #include <string.h> 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; } }
Processing File:
void processFile(Node ** Head, FILE * fd) { char * input = malloc(sizeof(char)*SIZE); while(fgets(input,SIZE,fd) != NULL) { addOrdered(Head,input); } free(input); }
解决方案The Bug in your code is: Address assign to
newNode->Data->FName
becomes invalid once you callfree(input)
in processFile() function and access the free memory causes an 'Undefined Behavior' at run time.To correct your code:
instead of simple assignment like:
newNode->Data->FName = strtok(input," ");
Allocate and Copy in separate memory as below:
char *ptr = strtok(input," "); newNode->Data->FName = malloc(strlen(ptr)+1); strcpy(newNode->Data->FName, ptr);
Actually you were assigning memory address from
input
address space in addOrdered() and makesfree()
inprocessFile()
function.I explain your code elaborate way below:
First read: char * strtok ( char * str, const char * delimiters ); manual:
On a first call, the function expects a C string as argument for str, whose first character is used as the starting location to scan for tokens. In subsequent calls, the function expects a null pointer and uses the position right after the end of last token as the new starting location for scanning.
Return Value
A pointer to the last token found in string. A null pointer is returned if there are no tokens left to retrieve.
It doesn't sends a new memory but memory from
input
that you lately free(). To understand strtok() function work I written following code: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; }
An execution of above program (address can be different at each run):
~$ ./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
Notice:
pch
address are from/withinstr
address scape.Similarly in your code, assign to
newNode->Data->FName = strtok(input," ");
inaddOrdered()
function. memory address value atnewNode->Data->FName
is in/frominput
that you latterly free inprocessFile()
function SonewNode->Data->FName
become invalid and your code runs as undefined behaviorvoid 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"
Second, you should read one less char from file in buffer, keep space for null
\0
.fgets(input, SIZE-1, fd)
这篇关于链表数据都是一样的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!