gpt4 book ai didi

c - C 中的结构分配导致内存覆盖(我认为)

转载 作者:太空狗 更新时间:2023-10-29 15:26:53 26 4
gpt4 key购买 nike

我以为我理解了这些东西,但我被难住了。

给定一个结构声明为:

typedef struct _Thing {
uint32_t type;
struct _Thing *children;
unsigned long childCount;
char *description;

union {
uint32_t thirtyTwoBitValue;
char *nameValue;
} data;

} Thing;

我有一个方法可以重新分配数组以容纳添加新的 Thing 对象。它看起来像这样:

void AddTopLevelThing(Thing *thing)
{
Thing *oldThings = things;
things = malloc(sizeof(Thing) * thingCount +1);

// Add any existing things to the new array
for (int i = 0; i < thingCount; ++i) {
things[i] = oldThings[i];
}

// Add the newest thing to the new array
things[thingCount] = *thing;

// Increment the thing count
thingCount++;
}

注意:things 和 thingCount 是全局变量。别 panic 。 ;-) 哦,我也意识到这是泄漏。一次一个问题...

为了创建我的 Thing 对象,我创建了一个初始化函数。它看起来像这样:

Thing* CreateThingWithDescription(char *description)
{
Thing *thing = malloc(sizeof(Thing));
if (thing == NULL) {
printf("Bad thing!, Bad!\n");
return NULL;
}

// Initialize everything in the structure to 0
memset(thing, 0, sizeof(Thing));

thing->children = NULL;
thing->description = strdup(description);

return thing;
}

为了使事情复杂化(没有双关语意),一个 Thing 对象有一个子对象数组,当新对象添加到它时,这些子对象会被重新分配(增长)。它看起来像这样:

void AddChildThingToThing(Thing *parent, Thing *child)
{
Thing *oldChildren = parent->children;
parent->children = malloc(sizeof(Thing) * parent->childCount + 1);
if (parent->children == NULL) {
printf("Couldn't allocate space for thing children.\n");
parent->children = oldChildren;
return;
}

// Add any existing child things to the new array
for (int i = 0; i < parent->childCount; ++i) {
parent->children[i] = oldChildren[i];
}

// Add the newest child thing to the new array
parent->children[parent->childCount] = *child;

// Increment the child count
parent->childCount = parent->childCount + 1;
}

无论如何,我很难弄清楚为什么当我完成创建我的结构并添加子结构时,它们经常被清零,即使我在创建它们时验证了它们的创建(在调试器中)。当我的 main 中的代码完成运行时,我应该有一个树结构,但它只是一堆我不认识或不理解的乱七八糟的值——这就是为什么我相信事情会被覆盖。

无论如何,我希望我只是忽略了一些简单的事情。

如果您想了解我如何构建对象层次结构,这是我的主要内容:

int main(int argc, const char * argv[])
{
things = NULL;
thingCount = 0;

Thing *thing = CreateThingWithDescription("This is thing 1");
SetThingName(thing, "Willy Johnson");
AddTopLevelThing(thing);
Thing *child = CreateThingWithDescription("This is child thing 1");
SetThingName(child, "Willy's Son");
AddChildThingToThing(thing, child);
child = CreateThingWithDescription("This is child thing 2");
SetThingName(child, "Willy's Daughter");
AddChildThingToThing(thing, child);

thing = CreateThingWithDescription("This is thing 2");
SetThingValue(thing, 700);
AddTopLevelThing(thing);
child = CreateThingWithDescription("This is child thing 3");
SetThingValue(child, 1024);
AddChildThingToThing(thing, child);

for (int i = 0; i < thingCount; ++i) {
PrintThing(&things[i]);
}
return 0;
}

注意:这只是一个演示项目,用于弄清楚发生了什么。

最佳答案

您需要在 AddTopLevelThing 函数中多分配一个结构,而不是多分配一个字节:

things = malloc(sizeof(Thing) * (thingCount+1));

另外,在重新分配后,您不会释放旧的内存块。并且最好使用 realloc('realloc' 负责复制旧数据和释放旧内存;它有时也可以“就地”执行重新分配,效率更高):

void AddTopLevelThing(Thing *thing) {
thingCount++;
things = realloc(things, sizeof(Thing) * thingCount);
things[thingCount-1] = *thing;
}

关于c - C 中的结构分配导致内存覆盖(我认为),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16967601/

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