c-指针指向另一个结构的结构中的分段错误



我的链表有一些问题。我将struct dListNode用作列表的节点,并将指针指向用作数据存储的struct data

struct data{
    int payload;
};
struct dListNode{
    struct dListNode *next;
    struct dListNode *prev;
    struct data *val;
}*dHead, *dTail;

我的程序编译得很好,但在下面的行中出现了分段错误。发生了什么事?

newDNode = (struct dListNode *)malloc(sizeof(struct dListNode)+sizeof(struct data));
printf("newnode createdn"); // this prints
newDNode->val->payload = rand() % 1000; //error here?
printf("newnode payload: %in", newDNode->val->payload); //seg fault before this is printed

此外,我已经在程序中运行了这一行:srand((unsigned)time(NULL))

NewDNode没有相关的内存分配

newDNode = (struct dListNode *)malloc(sizeof(struct dListNode)+sizeof(struct data));

这只是将内存分配给newDnode而不是newDnode->val。由于newDNode->val只包含该位置内存中剩余的内容(甚至可能是0(NULL指针((,并且您试图为既不在堆栈上也不在堆上的内存位置分配一个值,因此程序会抱怨,因为您试图访问未分配的内存部分。

以下是您应该做的:

newDNode = malloc(sizeof(struct dListNode));
newDnode->val = malloc(sizeof(struct data));
printf("newnode createdn");
newDNode->val->payload = rand() % 1000;
printf("newnode payload: %in", newDNode->val->payload);

作为提示,请始终尝试不强制转换malloc(或任何其他内存分配函数(返回的结果。这被认为是不好的做法。

您的问题是从未初始化指针val:

newDNode->val->payload = rand() % 1000;

分配了newDNode,但没有初始化任何字段,因此取消引用val可能会导致分段错误。

因此,在访问val之前,您需要为其分配一些内容。

newDNode = malloc(sizeof(struct dListNode));   //  Allocate "dListNode"
newDNode->val = malloc(sizeof(struct data));   //  Allocate "data"
newDNode->val->payload = rand() % 1000;

您对分配的工作方式有点误解。您需要分别分配每个指针。

编辑:另一种方法是首先不使用val的指针:

//  Declare struct as:
struct dListNode{
    struct dListNode *next;
    struct dListNode *prev;
    struct data val;
}*dHead, *dTail;

//  Build object like this:
newDNode = malloc(sizeof(struct dListNode));
newDNode->val.payload = rand() % 1000;

val未指向有效的data结构。当然,malloc的大小足够了,但这并不意味着val现在突然变成了一个有效的指针。您应该用dListNode的大小初始化newDNode,然后单独初始化newDNode->val,以指向某个足够大的有效内存块,用于data结构。

附带说明一下,您不需要强制转换malloc的返回值。这是一个C++的东西;在C中,CCD_ 22可以隐式地转换为任何其他指针类型。

第二,如果您的结构类型为typedef,那么在使用它们时不必到处写struct

您从未将newDNode->val设置为指向任何对象。因此,当您尝试设置newDNode->val->payload时,您正在取消引用空指针或某个随机地址(我忘记了是哪个(。这两种情况都不是你想要的。

我真的不喜欢在同一个语句中对两个结构进行malloc’in的想法。但如果你坚持这样做,你需要做一些类似的事情

newDNode->val = (struct data*)((char*) newDNode + sizeof(struct dListNode));

不过,更好的方法是更改结构,使val是一个结构,而不仅仅是指向一个结构的指针。然后sizeof(struct dListNode)包括struct data的大小,您可以像newDListNode->val.payload一样访问它,而不必单独对数据部分进行malloc或进行任何棘手的指针计算。(缺点是,您必须复制结构以将它们存储在阵列中,交换它们,等等(

相关内容

  • 没有找到相关文章

最新更新