为什么 printf 会在链表中导致段错误?
Why does printf cause a segfault in a linked list?
我的代码接受一串由空格分隔的整数,并从中构建一个链表,-1 除外。为什么打印 nextNode -> data
会导致段错误?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node Node;
struct node {
int data;
Node *next;
};
void build_linked_list(Node **head_ptr) {
char *string = malloc(1028);
char *p = string, *found = string;
Node *nextNode = NULL;
if (fgets(string, 1028, stdin) != NULL) {
while ((found = strsep(&p, " \n")) != NULL) {
if (strcmp(found, "-1") == 1) {
Node *node = malloc(sizeof(Node));
node->data = atoi(found);
node->next = nextNode;
nextNode = node;
}
}
}
*head_ptr = nextNode;
printf("%i\n", nextNode->data); //error here
free(string);
}
int main() {
Node *head = NULL;
build_linked_list(&head);
return EXIT_SUCCESS;
}
你尝试在任何情况下打印 nextNode->data
,但是如果 nextNode
是 NULL
怎么办?尝试访问无效指针的成员将导致分段错误。
详情:
你把指针初始化为NULL
Node *nextNode = NULL;
你更新指针,但是只在特定条件下:
if (fgets(string, 1028, stdin) != NULL) {
while ((found = strsep(&p, " \n")) != NULL) {
if (strcmp(found, "-1") == 1) {
/* ... */
nextNode = node;
}
}
}
你打印字段
printf("%i\n", nextNode->data); //error here
但如果不满足条件,指针可能仍为NULL
要解决此问题,请在取消引用之前检查指针:
if( nextNode )
{
printf("%i\n", nextNode->data);
}
else
{
printf("NULL nextnode\n");
}
您在阅读 nextNode->data
之前没有检查是否 nextNode != NULL
。
strcmp() returns an integer indicating the result of the comparison,
as follows:
· 0, if the s1 and s2 are equal;
· a negative value if s1 is less than s2;
· a positive value if s1 is greater than s2.
当两个字符串不同时从 strcmp()
返回的内容不一定是 1
,因此 strcmp(found, "-1") == 1
是检查 found
是否不是 [=] 的错误表达式18=].
似乎 strcmp()
在您的环境中返回了 1
以外的东西,并且没有执行插入,因此 NULL
在 nextNode->data
处取消引用,调用分段错误。
试试这个:
void build_linked_list(Node **head_ptr) {
char *string = malloc(1028);
char *p = string, *found = string;
Node *nextNode = NULL;
if (fgets(string, 1028, stdin) != NULL) {
while ((found = strsep(&p, " \n")) != NULL) {
/* use != 0 to check string inequility and avoid processing empty string */
if (strcmp(found, "-1") != 0 && strcmp(found, "") != 0) {
Node *node = malloc(sizeof(Node));
node->data = atoi(found);
node->next = nextNode;
nextNode = node;
}
}
}
*head_ptr = nextNode;
if (nextNode != NULL) { /* check if nextNode is not NULL */
printf("%i\n", nextNode->data); //error here
}
free(string);
}
我的代码接受一串由空格分隔的整数,并从中构建一个链表,-1 除外。为什么打印 nextNode -> data
会导致段错误?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node Node;
struct node {
int data;
Node *next;
};
void build_linked_list(Node **head_ptr) {
char *string = malloc(1028);
char *p = string, *found = string;
Node *nextNode = NULL;
if (fgets(string, 1028, stdin) != NULL) {
while ((found = strsep(&p, " \n")) != NULL) {
if (strcmp(found, "-1") == 1) {
Node *node = malloc(sizeof(Node));
node->data = atoi(found);
node->next = nextNode;
nextNode = node;
}
}
}
*head_ptr = nextNode;
printf("%i\n", nextNode->data); //error here
free(string);
}
int main() {
Node *head = NULL;
build_linked_list(&head);
return EXIT_SUCCESS;
}
你尝试在任何情况下打印 nextNode->data
,但是如果 nextNode
是 NULL
怎么办?尝试访问无效指针的成员将导致分段错误。
详情:
你把指针初始化为
NULL
Node *nextNode = NULL;
你更新指针,但是只在特定条件下:
if (fgets(string, 1028, stdin) != NULL) { while ((found = strsep(&p, " \n")) != NULL) { if (strcmp(found, "-1") == 1) { /* ... */ nextNode = node; } } }
你打印字段
printf("%i\n", nextNode->data); //error here
但如果不满足条件,指针可能仍为NULL
要解决此问题,请在取消引用之前检查指针:
if( nextNode )
{
printf("%i\n", nextNode->data);
}
else
{
printf("NULL nextnode\n");
}
您在阅读 nextNode->data
之前没有检查是否 nextNode != NULL
。
strcmp() returns an integer indicating the result of the comparison, as follows:
· 0, if the s1 and s2 are equal; · a negative value if s1 is less than s2; · a positive value if s1 is greater than s2.
当两个字符串不同时从 strcmp()
返回的内容不一定是 1
,因此 strcmp(found, "-1") == 1
是检查 found
是否不是 [=] 的错误表达式18=].
似乎 strcmp()
在您的环境中返回了 1
以外的东西,并且没有执行插入,因此 NULL
在 nextNode->data
处取消引用,调用分段错误。
试试这个:
void build_linked_list(Node **head_ptr) {
char *string = malloc(1028);
char *p = string, *found = string;
Node *nextNode = NULL;
if (fgets(string, 1028, stdin) != NULL) {
while ((found = strsep(&p, " \n")) != NULL) {
/* use != 0 to check string inequility and avoid processing empty string */
if (strcmp(found, "-1") != 0 && strcmp(found, "") != 0) {
Node *node = malloc(sizeof(Node));
node->data = atoi(found);
node->next = nextNode;
nextNode = node;
}
}
}
*head_ptr = nextNode;
if (nextNode != NULL) { /* check if nextNode is not NULL */
printf("%i\n", nextNode->data); //error here
}
free(string);
}