我的名为Table
的结构包含一个名为Object
的结构数组。 Object包含指向另一个Object
的指针。我想创建两个方法 - 一个释放Object
,另一个释放Table
时指向这些结构的指针(分别为ObjectP
和TableP
):
这是我目前的天真实现,由于valgrid在整个地方吐出警告(我真的很想从Java中获取c),这绝对不起作用:
/*
* Represents a linked list containing a key value
*/
typedef struct Object {
void *key;
struct Object *top;
struct Object *next;
Boolean originalCell;
} Object;
/*
* Represents a table that stores keys based on a given object's hash
*/
typedef struct Table{
Object *linkedObjects;
size_t size, originalSize;
HashFcn hfun;
PrintFcn pfun;
ComparisonFcn fcomp;
Boolean wasDuplicated;
} Table;
void FreeObject(ObjectP object)
{
free(object);
}
void FreeTable(TableP table)
{
free(table);
}
我应该如何正确地释放这些结构?
编辑:
这是我分配变量的方式:
ObjectP CreateObject(void *key)
{
struct Object *object = (struct Object*) malloc(sizeof(struct Object));
...
}
TableP CreateTable(size_t tableSize, HashFcn hfun, PrintFcn pfun, ComparisonFcn fcomp)
{
struct Table *table = malloc(sizeof(Table));
if (table==NULL)
{
ReportError(MEM_OUT);
return NULL;
}
table->linkedObjects = NULL;
table->linkedObjects = malloc(tableSize * sizeof(Object));
...
}
答案 0 :(得分:2)
我不喜欢你的ObjectP
和TableP
符号;我将使用Object *
和Table *
明确指出。
从评论中,您只关心删除整个表格;这很好,因为它比删除任意对象简单得多。
我假设tableSize
的{{1}}参数存储在CreateTable()
中。
table->size
static Object *FreeObject(Object *obj)
{
Object *next = 0;
if (obj != 0)
{
free(obj->key); // If you allocated this
next = obj->next;
free(obj);
}
return(next);
}
void FreeTable(Table *tab)
{
if (tab != 0)
{
for (size_t i = 0; i < tab->size; i++)
{
Object *next = tab->linkedObjects[i].next;
while ((next = FreeObject(next)) != 0)
;
free(tab->linkedObjects[i].key); // If you allocated this
}
free(tab->linkedObjects);
free(tab);
}
}
函数是静态的,因为它仅供FreeObject()
使用。它删除密钥,假设在分配对象时分配了密钥;它捕获指向列表中下一个项目的指针(可能是空指针),释放对象本身,并返回指向下一个项目的指针。
FreeTable()
函数使用FreeTable()
函数释放挂起在名为FreeObject()
的数组中分配的对象的链接对象列表中的所有对象,然后删除对象数组,然后删除表。
释放内存时的关键是确保每个分配都有一个空闲,每个分配只有一个空闲。传递给linkedObjects
的值必须是free()
,malloc()
或calloc()
的值。请注意,realloc()
可以更改以前分配的地址,但必须释放realloc()
的值,而不是realloc()
或malloc()
的原始分配。
答案 1 :(得分:2)
为了删除整个表(以及对象),您需要遍历对象图并为通过malloc分配的每个块调用free()
,即一个Object
或其中一个数组
我理解您的对象图如下所示:
然后删除的方法是:
void FreeObjectChain(Object* obj) {
Object* curr = obj->next;
while (curr) {
Object* tmp = curr;
curr = tmp->next;
free(tmp);
}
}
和
void FreeTable(Table* table) {
for (int i=0; i<table->size; ++i) {
FreeObjectChain( &(table->linkedObjects[i]) );
// or simply FreeObjectChain( table->linkedObjects + i );
}
free(table->linkedObjects);
free(table);
}
答案 2 :(得分:1)
我会尝试做类似的事情:
void freeObject(Object* obj) {
if (obj->next != NULL) {
freeObject(obj->next);
}
if (obj->key != NULL) {
free(obj->key);
}
free(obj);
}
void freeTable(Table* table) {
for (int i=0; i<table->size; ++i) {
freeObject(&(table->linkedObjects[i]));
}
freeObject(table->linkedObjects);
free(table);
}
答案 3 :(得分:0)
FreeTable()必须遍历数组并在所有对象上调用free()。
在尝试任何处理内存管理的代码之前,您应首先了解/了解计算机在低级别范围内的工作方式。