我的主要问题是,我的计划只是简单的糟糕做法吗?能做到吗?应该做吗? 我正在编写一个小小的键值对“字典”结构,只是为了熟悉 C。我编写的函数之一旨在返回与所提供的键关联的所有值的字符串数组。函数定义:
char** get_values(const struct dict* d, const char* key)
{
// if key does not exist
if(contains_key(d, key) == 0)
{
return NULL;
}
// count the number of times the key occurs in the dict
int count = count_keys(d, key);
// make a return value
char** key_values = alloc_list(count);// definition included below
int curr_count = 0;
// fill return array
for(int pos = 0; pos < DSIZE; pos++)
{// if current key in dict matches requested key...
if(strcmp(d->keys[pos], key) == 0)
{
// add current value to return array
strcpy(key_values[curr_count], d->values[pos]);
curr_count++;
}
}
return key_values;
}
该函数为字符串数组分配内存:
static char** alloc_list(int count)
{
// Allocate list of strings
char** slist = (char**)malloc(sizeof(char*) * count);
// if allocation was great success...
if(slist)
{
// ... allocate memory for each string
for(int pos = 0; pos < DSIZE; pos++)
{
slist[pos] = (char*)malloc(DSIZE * sizeof *slist[pos]);
}
}
return slist;
}
然后在main()中:
add(&dictionary, "a", "a");
add(&dictionary, "a", "aa");
add(&dictionary, "a", "aaa");
char** a_val = get_values(&dictionary, "a"); // TODO: how do I free this!
assert(strcmp(a_val[0], "a") == 0);
assert(strcmp(a_val[1], "aa") == 0);
assert(strcmp(a_val[2], "aaa") == 0); // all these assertions pass
free(*a_val); // with * omitted, execution aborts, with * included, no warnings
// from gcc, yes I am stabbing in the dark here.
a_val = NULL;
我不相信最后两行正在做我希望它们做的事情,当我在 gdb 中打印 a_val[0-2] 的值时,它们仍然在那里。 我意识到我可以通过在 main() 中分配一个字符串数组来解决这个问题,然后更改 get_values() 以接受该数组,然后让 get_values() 执行其任务,然后在我执行操作时 free() 分配的字符串数组完成了。但在我继续这样做之前,我只是想看看是否以及如何从调用函数中释放内存。我读过一些相关内容,其中所说的只是“在调用函数中释放内存是程序员的责任”,但书中没有说明如何应对这种情况。
预先感谢您的帮助!
最佳答案
为了正确释放a_val
,您首先需要一个for循环来释放/释放之前分配的char数组,然后释放双指针(即a_val
)。否则,您将造成内存泄漏,因为 a_val
的元素/指针指向的内存将被未引用/孤立:
char** a_val = get_values(&dictionary, "a");
...
for(int pos = 0; pos < DSIZE; pos++) {
free(a_val[pos]);
}
free(a_val);
声明free(*a_val);
相当于声明free(a_val[0])
。因此,只有 a_val
的第一个字符串将被释放。
关于C——从调用函数中释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25215155/