0

我有以下 C 程序。当我包含以下行时它会起作用,否则会出现分段错误:

printf("head(%p), last(%p), newnode(%p)\n", head, last, newnode);

知道这里有什么问题吗?

这是我的整个程序。这是一个基本的循环队列示例。

#include "stdio.h"
#include "malloc.h"

struct node {
    int data;
   struct node *next;
};

typedef struct node NODE;

void display(NODE *);

int main(void) {

    NODE *head, *last, *newnode = NULL;
    int i = 5;

    for ( ; i > 0; i--) {
        newnode = (NODE *) malloc(sizeof(NODE));
        newnode->data = i*10;
        newnode->next = NULL;

        //printf("head(%p), last(%p), newnode(%p)\n", head, last, newnode);


        if (head == NULL) {
            head = newnode;
            last = newnode;
        } else {
           last->next = newnode;
           last = newnode;
        }

        last->next = head;
    }

    display(head);

    return 1;
}

void display(NODE *head) {

    NODE *temp = NULL;
    temp = head;

    printf("Elements --> ");
    do {
            printf("%d ", temp->data);
            temp = temp->next;
    } while (temp != head);

    printf("\n");

}
4

3 回答 3

7

head还需要显式初始化。lastNULL

在您的声明中:

NODE *head, *last, *newnode = NULL;

只有 newnode被初始化为NULL. 因此,稍后在您的 if/else 中,您正在测试/分配给随机内存。

做这样的事情:

NODE *head, *last, *newnode;
head = last = newnode = NULL;

不能假设指针会自动初始化为NULL,即使在某些系统上可能是这种情况。声明为的变量static是一个例外。始终将 C 中的变量初始化为合理的值,尤其是指针。

当您访问垃圾内存时,您正在调用未定义的行为。当您这样做时,您可能会观察到不一致和令人困惑的结果。在您的情况下,添加printf 似乎可以解决问题。这会影响您的代码行为的原因是依赖于实现,并且 - 一旦您引入了未定义的行为 - 就超出了您的控制范围。

于 2012-07-08T18:59:29.923 回答
3

last并且head没有被初始化。您可以打开编译器警告来帮助您:

$ gcc -O1 -Wall w.c -o we
w.c: In function ‘main’:
w.c:30:23: warning: ‘last’ may be used uninitialized in this function [-Wuninitialized]
w.c:26:12: warning: ‘head’ may be used uninitialized in this function [-Wuninitialized]

(请注意,gcc 需要-O1for-Wuninitialized工作。)

于 2012-07-08T19:00:56.900 回答
2

你没有初始化head并且last

NODE *head, *last, *newnode = NULL;

所以他们有任何垃圾位在他们被分配的地方,if (head == NULL)即使head没有正确设置也可能失败。也将它们初始化NULL

于 2012-07-08T18:59:51.380 回答