[英]Segmentation Fault during linked list in c
I am getting a segfault when I try and print out my linked list. 尝试打印链接列表时出现段错误。 Can anyone explain why?
谁能解释为什么? I am aware a segfault means that I am accessing memory I am not supposed to.
我知道,segfault意味着我正在访问不应该访问的内存。 I am assuming this means I am not setting up my pointers right.
我假设这意味着我没有正确设置指针。 Any help would be great.
任何帮助都会很棒。 My code...
我的代码...
#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;
}
This: 这个:
scanf("%s", &word);
is a buffer overflow, since %s
will read a string , but you only have a single character. 是缓冲区溢出,因为
%s
将读取一个字符串 ,但是您只有一个字符。 This invokes undefined behavior; 这会引起未定义的行为; even if you enter just a single character,
scanf()
will add 0-termination after that character to make a proper string. 即使您仅输入一个字符,
scanf()
也会在该字符后添加0终止符以构成正确的字符串。
Change the declaration of word
: 更改
word
的声明:
char word[32];
And scan with an explicit size, to prevent scanf()
from writing outside the buffer: 并以明确的大小进行扫描,以防止
scanf()
在缓冲区外写入:
scanf("%30s", word);
Also check the return values of all I/O and memory allocation calls, since they can fail. 还要检查所有I / O和内存分配调用的返回值,因为它们可能会失败。
Finally, don't cast the return value of malloc()
, in C . 最后, 不要在C中
malloc()
的返回值 。
Regarding the memory leaks, can I suggest you fix them with the following code: 关于内存泄漏,我是否可以建议您使用以下代码修复它们:
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
}
This frees the already printed head
in each iteration of the loop. 这将在循环的每次迭代中释放已打印的
head
。
The other issues are already addressed by other posters. 其他问题已经由其他张贴者解决。
Initialize the *head
pointer as 初始化
*head
指针为
item *curr=NULL, *head = NULL;
without this, the if
will not execute and you would access some random memory for head
node. 否则,
if
将不会执行,您将访问head
节点的一些随机内存。 The while
loop for printing the linked list may not terminate and keep accessing invalid memory. 打印链接列表的
while
循环可能不会终止,并继续访问无效的内存。
if (head == NULL){
...
}
You have been caught out by scanf
. 您已经被
scanf
。 First you wish to read a single character and the format for that is %c
- %s
reads the next non-blank sequence of characters after skipping any leading whitespace. 首先,您希望读取一个字符 ,其格式为
%c
%s
在跳过任何前导空格后读取下一个非空白字符序列。 Using %s
causes the error, as it overwrites memory. 使用
%s
会导致错误,因为它会覆盖内存。
However if you change the format to %c
your code still won't work, and it's scanf
again. 但是,如果将格式更改为
%c
您的代码仍然无法使用,并且再次变为scanf
。 For most formats scanf
will skip leading whitespace, but it does not do this when reading characters. 对于大多数格式,
scanf
会跳过前导空格,但在读取字符时不会这样做。 So if you run your code you will see this: 因此,如果您运行代码,将会看到以下内容:
Would you like to enter an integer? (y/n) y
Enter an integer: 10
Would you like to enter an integer? (y/n) 10
The second time around scanf
has read the newline after the 10
into word
, that is not a y
, and then moved on to print out your list - the 10
at the end. scanf
的第二次读取10
到word
之后的换行符,即不是y
,然后继续打印输出列表-最后的10
。
To skip whitespace before a character you add a space into the format string, so the line becomes: 要在字符前跳过空格,请在格式字符串中添加一个空格,这样该行将变为:
scanf(" %c", &word);
That one change will allow your code to work but you should really do more checking. 这一更改将使您的代码能够正常工作,但您实际上应该进行更多检查。
scanf
will return the number of items it successfully found, you should check that to make sure the user really did enter a number etc., etc. As an example here is what happens if the user accidentally enters y
twice: scanf
将返回成功找到的项目数,您应检查并确保用户确实输入了数字等。例如,如果用户不小心输入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:
What has happened here is scanf("%d", &temp)
failed, returned 0
, and stored nothing into temp
. 这里发生的事情是
scanf("%d", &temp)
失败,返回0
,并且没有将任何内容存储到temp
。 However as you did not check the result your program continues and then the second y
is consumed by the next scanf(" %c", &word)
. 但是,由于您没有检查结果,因此您的程序继续运行,然后第二个
y
由下一个scanf(" %c", &word)
占用。
Also look at your if (head == NULL)
statement - this is not really necessary at all, you can replace the whole if
/ else
with just two lines... that is left as an exercise. 还要看看您的
if (head == NULL)
语句-根本不是必须的,您可以将整个if
/ else
替换为仅两行...作为练习。
HTH HTH
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.