当我尝试打印出我的链表时,我遇到了段错误。有谁能解释为什么?我知道segfault意味着我正在访问我不应该访问的内存。我假设这意味着我没有正确设置我的指针。任何帮助都会很棒。我的代码......
#include <stdio.h>
#include <stdlib.h>
struct node
{
int val;
struct node *next;
}*head;
typedef struct node item;
int main() {
item *curr, *head;
head = NULL;
char word = 'y';
//int num[10];
//int i = 0;
while (word == 'y'){
printf("Would you like to enter an integer? (y/n) ");
scanf("%s", &word);
if(word == 'y'){
int temp = 0;
printf("Enter an integer: ");
scanf("%d", &temp);
curr = (item *)malloc(sizeof(item));
curr->val = temp;
if (head == NULL){
head = curr;
head->next = NULL;
}
else {
curr->next = head;
head = curr;
}
}
}
curr = head;
while(curr != NULL) {
printf("%d\n", curr->val); //seg fault happens here
curr = curr->next ;
}
return 0;
}
答案 0 :(得分:4)
此:
scanf("%s", &word);
是缓冲区溢出,因为%s
将读取字符串,但您只有一个字符。这会调用未定义的行为;即使您只输入一个字符,scanf()
也会在该字符后添加0终结符以生成正确的字符串。
更改word
的声明:
char word[32];
使用显式大小扫描,以防止scanf()
在缓冲区外写入:
scanf("%30s", word);
同时检查所有I / O和内存分配调用的返回值,因为它们可能会失败。
答案 1 :(得分:0)
关于内存泄漏,我可以建议您使用以下代码修复它们:
while(curr != NULL) {
item* temp = curr; // store the current pointer
printf("%d\n", curr->val);
curr = curr->next ;
free(temp); //free the current one now that curr points to the next
}
这将在循环的每次迭代中释放已经打印的head
。
其他海报已经解决了其他问题。
答案 2 :(得分:0)
将*head
指针初始化为
item *curr=NULL, *head = NULL;
如果没有这个,if
将不会执行,您将访问head
节点的一些随机内存。用于打印链接列表的while
循环可能无法终止并继续访问无效内存。
if (head == NULL){
...
}
答案 3 :(得分:0)
你被scanf
抓住了。首先,您希望阅读单个字符,其格式为%c
- %s
在跳过后读取下一个非空白字符序列任何领先的空白。使用%s
会导致错误,因为它会覆盖内存。
但是,如果您将格式更改为%c
,那么您的代码仍然无效,而且scanf
会再次生效。对于大多数格式scanf
将跳过前导空格,但在读取字符时不执行此操作。因此,如果您运行代码,您将看到:
Would you like to enter an integer? (y/n) y
Enter an integer: 10
Would you like to enter an integer? (y/n) 10
scanf
第二次在10
之后读取换行符word
,而不是y
,然后继续打印出您的列表 - 最后的10
。
要在字符之前跳过空白,请在格式字符串中添加空格,以便该行变为:
scanf(" %c", &word);
一次更改将允许您的代码工作,但您应该做更多的检查。 scanf
将返回成功找到的项目数,您应该检查以确保用户确实输入了数字等等。例如,如果用户意外输入{{1},会发生什么两次:
y
此处发生的事件是Would you like to enter an integer? (y/n) y
Enter an integer: y
Would you like to enter an integer? (y/n) Enter an integer:
失败,返回scanf("%d", &temp)
,并且未将任何内容存入0
。但是,由于您没有检查结果,程序会继续,然后下一个temp
消耗第二个y
。
另请查看您的scanf(" %c", &word)
声明 - 这根本不是必需的,您可以用两行代替整个if (head == NULL)
/ if
...锻炼。
HTH