0

我试图在 C 中创建一个链接列表,但由于一些神秘的错误,程序崩溃了。

首先我尝试了这个:

typedef struct product_data product_data;

struct product_data {
 int product_code;
 int product_size;
 product_data *next;
};

product_data *products_head = NULL;
product_data *products_tail = NULL;

int main() {
    int newcode = 5;
    int newsize = 5;
    products_head->product_code = newcode;
    products_head->product_size = newsize;
    products_head->next = NULL;

    return 0;
}

不幸的是,程序在没有任何错误消息的情况下崩溃。

然后我改变了一些部分:

typedef struct product_data product_data;

struct product_data {
 int product_code;
 int product_size;
 product_data *next;
};

product_data *products_head = NULL;
product_data *products_tail = NULL;

int main() {
    product_data *newproduct;
    int newcode = 5;
    int newsize = 5;
    newproduct->product_code = newcode;
    newproduct->product_size = newsize;
    newproduct->next = NULL;

    products_head = newproduct;

    return 0;
}

这次没有崩溃,它似乎工作。我不知道为什么。

有任何想法吗?

提前致谢!

4

5 回答 5

4

它真的不起作用。您仍在取消引用无效指针:

product_data *newproduct;
int newcode = 5;
int newsize = 5;
newproduct->product_code = newcode;
newproduct->product_size = newsize;
newproduct->next = NULL;

但是,虽然在第一个版本中您要取消引用显式设置为 的指针NULL,但它会因应有的​​分段错误而崩溃。在这里,您正在取消引用一个包含堆栈上任何数据的指针,不幸的是它不会崩溃。这是未定义的行为,因此不一定会崩溃。

你必须让你的指针指向有效的内存,

newproduct = malloc(sizeof product_data);
于 2012-06-05T19:42:27.110 回答
1

您需要为 products_head 分配内存。现在,您只需将其设置为 NULL。要么不让它成为指针,要么使用 malloc。

于 2012-06-05T19:42:08.613 回答
1

在您的第一个示例中,您正在写入 NULL 指针。您需要products_head在取消引用之前为其分配空间。就像是

products_head = malloc(sizeof(product_data));

我不知道为什么你的第二个例子有效。它不应该。 newproduct是一个未初始化的变量,它可以指向任何地方。也许你只是走运了,它指向了一块未使用的有效内存。

于 2012-06-05T19:42:41.707 回答
0

这将起作用,直到它不起作用。您仍然没有为您的结构分配任何内存。但是由于一些运气,newproduct 指向了一些有效的内存位置。您面临的问题是 product_head 被手动设置为 null (即使这不是必需的,因为所有全局变量总是被初始化)。然而堆栈变量并没有被初始化,你很幸运(或者不幸的是它会导致你错过一个明显的编程错误)它恰好指向你地址空间中的某个有效位置。

您可以使用 printf("%p", newproduct); 打印 newproduct 的内容以查看它指向的位置;不幸的是,插入这一行可能会改变程序的行为。

于 2012-06-05T19:45:37.803 回答
0

“->”意在访问动态分配的结构中的元素,“.” 用于访问静态分配的结构中的元素。

这是一个例子:

typedef struct product_data product_data;

struct product_data {
    int product_code;
    int product_size;
    product_data *next;
};

product_data *products_head = NULL;
product_data *products_tail = NULL;

int main() {
    /* Allocate memory */
    product_data *newproduct = malloc(sizeof(product_data));
    int newcode = 5;
    int newsize = 5;

    products_head = newproduct;
    newproduct->product_size = newsize;
    newproduct->next = NULL;

    /* free memory */
    free(product_data);

    return 0;
}

但是请记住,对于您在链表中创建的所有新节点,您必须分配内存并释放该内存。用于检查您分配的所有内存是否已释放的好程序是 valgrind。如果你在尝试让链表首先手动绘制它时遇到逻辑错误,如下所示:

      [head]   [tail]
        |        |
        V        V
      [ a ] -> [ b ] -> null

请记住,head 和 tail 都是指针(因此它们不需要分配内存,它们只需要指向您想要的节点。

如果您仍然遇到问题,因为您的逻辑变得非常复杂,我建议您尝试学习 GDB(它是一个命令行调试器),它将帮助您逐步完成代码,以便您可以逐步了解正在发生的事情。这就是我第一次学习创建数据结构的方式。

祝你好运!

于 2012-06-05T19:53:40.247 回答