我是一个学习C的菜鸟,我一直在尝试增强Simple Object System .
我有一个如下所示的结构:
struct Room
{
Object proto;
Monster* bad_guy;
struct Room *north;
struct Room *south;
struct Room *east;
struct Room *west;
};
我想释放这个:
void Room_destroy(void* self)
{
Room* room=self;
if(room->bad_guy)
room->bad_guy->proto.destroy(room->bad_guy);
if(room->north)
room->north.proto.destroy(room->north);//same as Room_destroy
if(room->south)
room->north.proto.destroy(room->south);////same as Room_destroy
if(room->west)
room->north.proto.destroy(room->west);////same as Room_destroy
if(room->east)
room->north.proto.destroy(room->east);////same as Room_destroy
free(room->proto.description);
free(room);
}
假设有两个房间,Room* x
和 Room* y,这样 x 位于 y
的北
,调用该方法x
将调用 y
上的方法,该方法将在 x
上调用该方法,而 x
将在 y
上调用该方法,然后返回如此反复会导致死锁。我该如何解决这个问题?
如何释放此类内存以确保不会发生内存泄漏?
编辑:
我尝试实现一组函数来调用它,但我同时遇到了 StackOverflow
和 Segmentation failure
:
==6446== Stack overflow in thread 1: can't grow stack to 0xffe801ff8
==6446==
==6446== Process terminating with default action of signal 11 (SIGSEGV)
==6446== Access not within mapped region at address 0xFFE801FF8
==6446== at 0x400863: Room_destroy (ex19.c:55)
==6446== If you believe this happened as a result of a stack
==6446== overflow in your program's main thread (unlikely but
==6446== possible), you can try to increase the size of the
==6446== main thread stack using the --main-stacksize= flag.
==6446== The main thread stack size used in this run was 8388608.
==6446== Stack overflow in thread 1: can't grow stack to 0xffe801fe8
==6446==
==6446== Process terminating with default action of signal 11 (SIGSEGV)
==6446== Access not within mapped region at address 0xFFE801FE8
==6446== at 0x4A256A0: _vgnU_freeres (vg_preloaded.c:58)
==6446== If you believe this happened as a result of a stack
==6446== overflow in your program's main thread (unlikely but
==6446== possible), you can try to increase the size of the
==6446== main thread stack using the --main-stacksize= flag.
==6446== The main thread stack size used in this run was 8388608.
==6446==
==6446== HEAP SUMMARY:
==6446== in use at exit: 605 bytes in 12 blocks
==6446== total heap usage: 12 allocs, 0 frees, 605 bytes allocated
==6446==
==6446== LEAK SUMMARY:
==6446== definitely lost: 0 bytes in 0 blocks
==6446== indirectly lost: 0 bytes in 0 blocks
==6446== possibly lost: 0 bytes in 0 blocks
==6446== still reachable: 605 bytes in 12 blocks
==6446== suppressed: 0 bytes in 0 blocks
==6446== Reachable blocks (those to which a pointer was found) are not shown.
==6446== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==6446==
==6446== For counts of detected and suppressed errors, rerun with: -v
==6446== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Segmentation fault
这是我的代码:
void Room_destroy(void* self)
{ 房间*房间=自己; if(房间->坏人) 房间->bad_guy->proto.destroy(房间->bad_guy);
if(room->north && !avoid(caller,room->north))
room->north->proto.destroy(room->north);
else
caller=room->north;
if(room->south &&!avoid(caller,room->south))
room->south->proto.destroy(room->south);
else
caller=room->south;
if(room->west && !avoid(caller,room->west))
room->west->proto.destroy(room->west);
else
caller=room->west;
if(room->east && !avoid(caller,room->east))
room->east->proto.destroy(room->east);
else
caller=room->east;
free(room->proto.description);
//room->proto=NULL;
free(room);
}
避免方法在这里:
int avoid(Room* caller,Room* room)
{
if(caller!=room)
return 0;
return 1;
}
然后有一个 Map 结构,如下所示:
struct Map
{
Object proto;
Room *start;
Room* location;
};
在这个结构上,我像这样调用了 destroy 方法:
void Map_destroy(void* self)
{
Map *map=self;
if(map->start)
{
caller=map->start;
map->start->proto.destroy(map->start);
}
if(map->location)
{
caller=map->location;
map->location->proto.destroy(map->location);
}
}
当用户像这样中止程序时调用此函数:
case -1:
printf("Giving up? You suck\n");
if(game)
game->proto.destroy(game);
return 0;
最佳答案
假设在某个时刻,您使用了 addRoom
方法将您的房间添加到房间网络中。然后,您应该有一个方法 removeRoom
来执行相反的操作。
所以如果你的房子\建筑物\房间图处于状态S0,那么
S0-(add room x)-> S1 -(remove room x)-> S2.
S0
必须等于 S2
。所以你可以使用
removeRoom(network, x)
freeRoom(x);
要一次性删除所有内容,请使用
while(isEmpty(network) ){
x = getHead(network)
removeRoom(network, x)
freeRoom(x);
}
与C中的链表原理相同
关于c - 在具有相同类型成员的结构上使用 free,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20563659/