简体   繁体   English

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

[英]C — Deallocating memory from a calling function

My main question is, is my scheme just plain bad practice? 我的主要问题是,我的计划只是普通的不良做法吗? Can it be done? 能做到吗 Should it be done? 应该做吗? I'm writing a little dinky key-value pair "dictionary" structure just to familiarize my self with C. One of the functions I've written is intended to return an array of strings of all the values associated with a provided key. 我正在编写一个小巧的键值对“字典”结构,以使自己熟悉C。我编写的函数之一旨在返回与提供的键相关的所有值的字符串数组。 The function definition: 函数定义:

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;
}

This function allocates the memory for the string array: 此函数为字符串数组分配内存:

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;
}

Then in main(): 然后在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;

I don't believe the last two lines are doing what I hope they are doing, when I print the values of a_val[0-2] in gdb, they are still there. 我不相信最后两行正在做我希望他们正在做的事情,当我在gdb中打印a_val [0-2]的值时,它们仍然存在。 I realize I could fix this problem by allocating a string array in main(), and then change get_values() to accept the array and then let get_values() do its business, and then free() the allocated array of strings when I am done with it. 我意识到我可以通过在main()中分配一个字符串数组来解决此问题,然后更改get_values()以接受该数组,然后让get_values()处理其事务,然后在我处于空闲状态时释放()分配的字符串数组完成它。 But before I go ahead and do that, I was just wanted to see if and how one goes about deallocating memory from a calling function. 但是在继续进行之前,我只是想看看是否以及如何从调用函数中释放内存。 I've read a little bit about it, and all that was said was "it is the programmers responsibility to deallocate memory in the calling function", but the book did not say how for a situation such as this. 我已经读了一点,只是说“程序员有责任在调用函数中释放内存”,但是书中没有提到如何处理这种情况。

Thanks in advance for any help! 在此先感谢您的帮助!

In order to properly deallocate a_val you will need first a for-loop to free/deallocate the char arrays allocated previously and then free the double pointer (ie, a_val ). 为了正确地释放a_val您首先需要一个for循环来释放/释放先前分配的char数组,然后释放双指针(即a_val )。 Otherwise you will create a memory leak since the memory pointed by elements/pointers of a_val will be unreferenced/orphaned: 否则,由于a_val的元素/指针所指向的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);

Stating free(*a_val); 声明free(*a_val); is equivalent as stating free(a_val[0]) . 等效于声明free(a_val[0]) Thus only the first string of a_val is going to be deallocated. 因此,只有a_val的第一个字符串将被释放。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM