使用memcpy
并在c中构建通用HashTable时遇到设计问题。 HashTable将unsigned int
个密钥映射到void *
上的memcpy
数据。
// Random example
void foo() {
// Suppose `a` is a struct that contains LinkedLists, char arrays, etc
// within it.
struct *a = malloc(sizeof(a));
HashTable ht = ht_create(sizeof(a));
// Insert the (key, value) pair (0, a) into the hash table ht
ht_insert(ht, 0, a);
// Prevent memory leak
destroy_struct(a);
// Do stuff...
// ... eventually destroy ht
ht_destroy(ht);
}
现在,鉴于struct a
中有LinkedLists和指针,而HashTable正在使用memcpy
,我的理解是它复制了这些指针的浅层副本。因此,ht_insert
mallocs空间用于新条目,浅层复制来自a
的数据,并将新条目插入其表中。
因此,除非我完全释放struct a
一些函数destroy_struct
,否则我会泄漏记忆。但是,鉴于我在ht_insert
中浅层复制数据,当我调用destroy_struct(a)
时,我也会意外地释放哈希表条目中指向的数据!
上面的逻辑是否正确,如果是,我应该使用一些递归memcpy函数,确保将所有数据从struct a
深度复制到HashTable?
答案 0 :(得分:2)
首先,如果您的代码没有重现您正在解释的问题,则不应包含它。代码产生的问题是编译器错误。这对你的问题没有帮助,是吗?
现在,给定struct a中有LinkedLists和指针,而HashTable使用memcpy,我的理解是它复制了这些指针的浅拷贝。
如果您只是将struct whatever *
的内部表示复制到void *
的内部表示中,那么您就是在寻找麻烦。无法保证两个表示形式完全相同。一个指针类型可能比另一个更大,它们使用不同的 endianness (如果它们被实现为典型的准整数)或者可能存在其他内部差异。你应该将一个指针转换为另一个类型,然后你可以简单地指定它...事实上,因为其中一种类型是void *
,当你分配时,转换将隐式发生。
因此,除非我完全释放
struct a
一些函数destroy_struct
,否则我会泄漏记忆。
根据您的描述,您只应在指针值上调用free
一次(并且只有一次),并且程序不再有任何用处(例如在之后将其从哈希表中删除)。这适用于malloc
,realloc
或calloc
返回的所有非空指针。 澄清:如果x
和y
存储其中一个函数返回的相同指针,free
只应在上调用 ONCE 其中一个因为它们包含相同的值。
上面的逻辑是否正确,如果是,我应该使用一些递归memcpy函数,确保将所有数据从struct a深度复制到HashTable?
我强烈建议将这个问题分成两个或多个单独的问题,因为它是双管齐下的。我可以简单地回答“是”(或“否”)。这会给你任何有意义的信息吗?
这让我回到我最初的写作。我只能根据你在这里写的内容来指导你,这可能不会反映你使用的代码(特别是考虑到你给出的错误代码的影响)。为了更好地指导你,我需要看到填补的所有空白。我需要看到一个创建哈希表的测试用例,插入哈希表,使用哈希表,从哈希表中删除并清除哈希表到确定您的操作是否在任何地方泄漏...... 但最重要的是,此测试用例需要 COMPILABLE !否则它无法执行任何操作,因为它无法编译。