C——从调用函数中释放内存

标签 c free

我的主要问题是,我的计划只是简单的糟糕做法吗?能做到吗?应该做吗? 我正在编写一个小小的键值对“字典”结构,只是为了熟悉 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/

相关文章:

c - C中的自由动态二维矩阵

c - 释放它们后真的应该将指针设置为 `NULL` 吗?

c/linux无限循环应用: deallocate memory if kill -9 command is called

c - 使用 free() 释放内存

c - Linux C,如何安排10个等待线程以FIFO方式执行?

c - 由于变量导致的内存添加是在 while 循环中初始化的

将 float 从 0 转换为 1 到 RGB 16bit

c - 如何在C中删除二叉树中的元素?

c - 为什么给 ReadFileEx() 的回调没有收到正确的 OVERLAPPED 结构?

c - 在C中生成1000字节的十六进制数