为啥我的链表内容在退出函数时会消失?
Posted
技术标签:
【中文标题】为啥我的链表内容在退出函数时会消失?【英文标题】:Why is my content of linked list disappear when it exit a function?为什么我的链表内容在退出函数时会消失? 【发布时间】:2022-01-13 01:31:41 【问题描述】:我试图扫描文件并将数据添加到链接列表中,然后将操作打印到输出文件中。我成功将操作打印到输出文件,但是当我尝试访问它时,我的链接列表的内容是空的。
然后我检查创建和链接的每个节点的地址,发现没有问题,当它在函数内部时,链接列表工作正常,但在 main() 中没有。
输入.txt 3 1 编码标记编程 1 烹饪米妮烹饪 1 园艺一分钱植物学
此代码未完成,但包含我的问题:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
struct book
char *title;
char *author;
char *subject;
;
struct library
struct book collection;
int num_books;
struct library *next;
;
void AddBook(FILE *IF, FILE *OF, struct library** thislib);//function prototype
int main(void)
FILE *IF,*OF;
int sel,numOp,i;
struct library *Lib=NULL;//declare head pointer
if(((IF=fopen("library.txt","a+"))==NULL)||((OF=fopen("output.txt","w"))==NULL))//open input and output file
printf("File cannot be open!");
else
fscanf(IF," %d",&numOp); //scan the number of operation from file
for(i=0;i<numOp;i++) //Loop according to number of operation
if(feof(IF)) //if file pointer reach EOF break
break;
fscanf(IF," %d",&sel); //scan the type of operation
switch(sel)
case 1:
AddBook(IF,OF,&Lib); //add the book if sel is 1
break;
case 2:
break;
printf("%s ", Lib->collection.title); // print the title of the book but it show nothing
return 0;
void AddBook(FILE *IF, FILE *OF, struct library** thislib)
char title[30],author[30],subject[20]; //declare variable to hold data
struct library *temp=NULL; //create a new node
struct library *ptr=*thislib; //create a pointer that point to head of link list
temp=(struct library*)malloc(sizeof(struct library)); //allocate memory for the new node
fscanf(IF," %s %s %s" ,title,author,subject);
temp->collection.title=title; // put the data into link list
temp->collection.author=author;
temp->collection.subject=subject;
temp->next=NULL;
if((*thislib)==NULL)
(*thislib)=temp; // if there is no content in link list put temp into head
else
while (ptr->next!=NULL)
ptr=ptr->next; //put node at the end of link list
ptr->next=temp;
fprintf(OF,"The book %s author %s subject %s has been added to the library.\n",title,author,subject);
printf("%s ",(*thislib)->collection.title); //this work fine but it keep updating, weren't it suppose to have the same value
【问题讨论】:
temp->collection.title=title;
将指向局部变量的指针放入列表节点。当函数返回时,这些指针变得无效。您需要制作字符串的动态副本,例如temp->collection.title=strdup(title)
嘿,它的工作非常感谢你,strcpy() 也工作吗?
在分配内存之前不能使用strcpy()
。 strdup()
是 malloc()
和 strcpy()
的组合。
【参考方案1】:
你忘了#include <stdlib.h>
。您的代码非常未定义,因为您剪掉了malloc()
返回的高位。
您返回了指向堆栈数组的指针。
temp->collection.title=title; // put the data into link list
temp->collection.author=author;
temp->collection.subject=subject;
得骗那些。 strdup()
是你的朋友:
temp->collection.title=strdup(title); // put the data into link list
temp->collection.author=strdup(author);
temp->collection.subject=strdup(subject);
此行在您的测试用例中失败:fscanf(IF," %d",&numOp);
输入与模式不匹配;您使用未定义的numOp
进入循环。 (我通过更正输入文件轻松解决了这个问题。您应该始终检查 scanf 的返回。)
此 scanf 导致读取问题导致废话。
fscanf(IF," %s %s %s" ,title,author,subject);
但您的输入中有四个以空格分隔的字段。
-
您的调试输出显示链接列表中的第一项,但您每次都追加到列表末尾,因此它不会更改。
“剪掉高位”的解释:
缺少#include <stddef.h>
的隐式声明将是int malloc(size_t)
,这是错误的。这在 32 位平台上有效,但在 64 位平台上无效。 int
向上转换为 void *
,这不会产生正确的值。
假设malloc()
返回了0x104C000010
。返回地址看起来像这样(字节顺序在这里无关紧要,原因我现在不打算讨论)
0 63
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|1|0|0|1|0|0|0|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
但是返回被解释为32位整数(大多数64平台有sizeof(int)
=4),所以会被解释为
0 31
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|1|0|0|1|0|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
当转换为 struct library *
时,会导致
0 63
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|1|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
这是0x4C000010
。哎呀,指向其他地方。任何事情都可能发生,但很可能是崩溃。
【讨论】:
“你剪掉了 malloc() 返回的高位”。怎么样? @MadPhysicist:隐式类型为int malloc(...);
,int
在现代平台上小于void *
。
剪掉高位是什么意思?会造成什么影响?
@Joshua。这是一个很好的选择,特别是如果 OP 的 RAM > 4GiB。您可能想在答案中为 OP 拼写出来。
@Strugle: #include <stdlib.h>
并在启用警告的情况下进行编译。这给出了“隐式声明”的警告。以上是关于为啥我的链表内容在退出函数时会消失?的主要内容,如果未能解决你的问题,请参考以下文章