gpt4 book ai didi

c - 中止陷阱 6 malloc

转载 作者:行者123 更新时间:2023-11-30 18:24:29 25 4
gpt4 key购买 nike

我正在尝试用 C 语言实现 n 叉树。运行它时出现以下错误:

sibling(1143,0x7fff7e925000) malloc: *** error for object 0x7f946b4032c8: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

我不确定是什么原因导致了该错误。正如它所说,我似乎正在写入一个已释放的对象。但在我的代码中,我没有释放任何分配的内存。我对 c 很陌生,这让我很困惑。我尝试使用 gdb 进行调试,它说错误是由 printTree(); 引起的;在 main 中调用我递归地尝试打印树。希望你能帮助我理解这个问题:-)。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
char *name;
unsigned int utility;
unsigned int probability;
} Child;

typedef struct {
unsigned int level;
unsigned int player;
unsigned int nChildren;
Child *children;
} Data;

typedef struct sNaryNode{
Data *data;
struct sNaryNode *kid;
struct sNaryNode *sibling;
} NaryNode;

NaryNode* createNode(Data data){
NaryNode *newNaryNode = malloc(sizeof (NaryNode*));
newNaryNode->sibling = NULL;
newNaryNode->kid = NULL;
newNaryNode->data = &data;
return newNaryNode;
}

NaryNode* addSibling(NaryNode* n, Data data){
if(n == NULL) return NULL;

while(n->sibling)
n = n->sibling;

return (n->sibling = createNode(data));
}

NaryNode* addChild(NaryNode* n, Data data){
if(n == NULL) return NULL;
else if(n->kid)
return addSibling(n->kid, data);
else
return (n->kid = createNode(data));
}

void printTree(NaryNode* n) {
if(n == NULL) return;

if(n->sibling) {
printf("%u %u %u %u %u %s", n->data->level, n->data->player, n->data->nChildren, n->data->children[0].probability, n->data->children[0].utility, n->data->children[0].name);
printTree(n->sibling);
}
else if(n->kid) {
printf("%u %u %u %u %u %s", n->data->level, n->data->player, n->data->nChildren, n->data->children[0].probability, n->data->children[0].utility, n->data->children[0].name);
printTree(n->kid);
}
else {
printf("The tree was printed\n");
}
}


int main(void) {
NaryNode *root = calloc(1, sizeof(NaryNode));
Data data;
data.level = 1;
data.player = 1;
data.nChildren = 2;
data.children = calloc(data.nChildren, sizeof data.nChildren);
data.children[0].probability = 50;
data.children[0].utility = 1;
data.children[0].name = "Kom med det første tilbud (anchor)";
data.children[1].probability = 50;
data.children[1].utility = 1;
data.children[1].name = "Afvent modspilleren kommer med første tilbud";
*root = *createNode(data);
int i = 0;
for(i=0; i<root->data->nChildren; i++) {
addChild(root, data);
}

printTree(root);
}

最佳答案

您的代码中存在各种错误。

  1. 分配大小不正确的内存块:

    data.children = calloc(data.nChildren, sizeof data.nChildren);

    data.childrenChild 的数组结构,但您分配的结构的大小等于 sizeof(unsigned int) ,由于 data.nChildrenunsigned int .

  2. 获取临时变量的地址并将其存储以供以后使用:

    NaryNode* createNode(Data data){
    newNaryNode->data = &data;
    }

    datacreateNode仅在函数运行时存在:在本例中,您将获取局部变量 data 的地址并将其存储在您要返回以供以后使用的结构中。这是一个非常糟糕的主意,因为该指针将引用函数返回后不再存在的对象。

    请记住,您不需要传递 Data 的副本对象进入 createNode在您当前的代码中,因为实际上只有一个 Data整个程序中的对象。因此,您可以更改 createNode 的原型(prototype)至createNode(Data* data) ,并传递 Data 的地址您在 main 中创建的结构。不过,我认为,做任何比这更复杂的事情都需要深度复制结构。

  3. 错误地管理对象的生命周期。

    NaryNode *root = calloc(1, sizeof(NaryNode));
    *root = *createNode(data);

    createNode返回 NaryNode* 。但是,您实际上从未将其分配给 NaryNode*以便您稍后可以释放它。相反,指向函数返回的对象的指针仅在 *root = *createNode(data) 期间已知。调用,后来就不可挽回地丢失了。但是,由于取消引用对象并将其复制到 root,您确实保留了对象的内容。 :但是,对象本身是从 createNode 返回的,丢失且不可恢复,除非指向它的指针仍然存在于树中。

关于c - 中止陷阱 6 malloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40959353/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com