【问题标题】:Memory leak because of seemingly necessary malloc repetition由于看似必要的 malloc 重复而导致内存泄漏
【发布时间】:2016-11-23 14:03:37
【问题描述】:

我有以下结构:

typedef struct pair {
  int *key;                // search key for this item
  int *count;                  // pointer to data for this item
  struct pair *next;   // children
} pair_t;

typedef struct counters {
  struct pair *head;
} counters_t;

我有以下功能:

static pair_t * // not visible outside this file
pair_new(const int key)
{

  pair_t *pair = malloc(sizeof(pair_t));

  free(pair->key);
  free(pair->count);

  if (pair == NULL) {
    // error allocating memory for pair; return error
    return NULL;
  } else {

      pair->key = malloc(sizeof(int));
      pair->count = malloc(sizeof(int));

      *(pair->key) = key;
      *(pair->count) = 1;
      pair->next = NULL;
      return pair;

  }
}

请注意,我首先为 pair 分配,检查内存是否正确分配,如果是,我将值分配给 pair 实例的元素。为了给这些元素(键和计数)赋值,我必须为它们(元素)分配内存。稍后在我的主程序中,我调用了删除函数:

(ctrs 是对的链表)

void counters_delete(counters_t *ctrs){
  if(ctrs!=NULL){
    pair_t *temp = ctrs->head;
    while(temp!=NULL){
      printf("freeing for key %d\n",*(temp->key));
      free(temp->count);
      free(temp->key);
      temp = temp->next;
    }
    ctrs->head=NULL;
  }
  return;
}

其中我释放了每对的密钥并计数。

因为我分配了一对的完整大小,然后再次为每对的元素分配,所以我留下了在程序结束时尚未释放的内存。我该如何解决这个问题?

【问题讨论】:

  • 为什么malloc后面有free(pair->key); free(pair->count);
  • ^^^^^^ ... 调用未定义的行为,因为这些指针是不确定的。
  • @WhozCraig Right 先生,已经将其转换为答案。 :)
  • @SouravGhosh.. 已经被上调 =)
  • 有什么理由不让keycount简单地ints?

标签: c pointers memory-leaks dynamic-memory-allocation


【解决方案1】:

首先,删除

free(pair->key);
free(pair->count);

malloc() 之后,因为在内存管理函数未返回的指针上调用free() 会调用undefined behavior

也就是说,一开始,你malloc()-ed 用于原始变量和成员,最后,你只释放结构变量的指针成员keycount,但是实际变量temp 仍然分配。这就是导致泄漏的原因。

你也必须释放temp

【讨论】:

  • “变量temp 仍然分配”是错误节点 保持分配状态。这与变量无关。
  • @immibis 我在完整句子的上下文中提到了这一点。为什么你只引用了一半?
【解决方案2】:

...我在程序结束时留下了尚未释放的内存。我该如何解决这个问题?

您必须先复制temp,然后再移动到下一个元素,然后在将temp移动到下一个元素后释放该元素。

pair_t *temp2 = temp;   // Add this before
temp = temp->next;
free(temp2);            // Add this after

另请参阅 Sourav Ghosh 关于删除对 free 的非法调用的回答

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-14
    • 2021-07-23
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多