【问题标题】:如何检查 C 中的内存泄漏?
【发布时间】:2022-01-23 15:24:32
【问题描述】:

这是我第一次使用动态内存分配,我不知道如何检查我的代码中的内存泄漏

一般来说,我如何检查 Visual Studio 中的内存泄漏?我不知道如何跟踪堆和堆栈,所以我主要是在黑暗中拍摄。

我应该提到我使用的是 Windows 10,据我所知 Valgrind 不提供对 W10 的支持

Dictionary* createDic(Dictionary* dics, int* size) {
    Dictionary* temp = NULL;
    //some extra code for the variables below which arent al that important for the question
    temp = malloc(++*size * sizeof(Dictionary));
    if (temp==NULL)
    {
        printf("\nThe creation of the dictionary has failed!");
        *size+=-1;
        freeArray(splitReciever,count);
        return dics;
    }
    for (int i = 0; i < (*size - 1); i++)
    {
        temp[i] = dics[i];
    }
    temp[*size - 1].languages = splitReciever;
    temp[*size - 1].numOfLanguages = count;
    temp[*size - 1].wordList = NULL;
    dics = temp;
    return dics;
}

我还想知道这段代码是否可以再次工作而不会导致内存泄漏?

Dictionary* createDic(Dictionary* dics, int* size) {
    Dictionary* temp = NULL;
    //some extra code for the variables below which arent al that important for the question
    temp = realloc(dics , ++*size * sizeof(Dictionary));
    if (temp==NULL)
    {
        printf("\nThe creation of the dictionary has failed!");
        *size+=-1;
        freeArray(splitReciever,count);
        return dics;
    }
    temp[*size - 1].languages = splitReciever;
    temp[*size - 1].numOfLanguages = count;
    temp[*size - 1].wordList = NULL;
    dics = temp;
    return dics;
}

【问题讨论】:

  • 你试过 Valgrind 吗?
  • 首先不要做“聪明”的事情,比如将 ++ 表达式与其他代码混合。

标签: c memory-leaks malloc dynamic-memory-allocation realloc


【解决方案1】:

可以使用valgrind 等工具检查内存泄漏——虽然这些工具不能保证(不)存在内存泄漏或查找任何内存泄漏的位置 - 可能存在误报和否定 - 他们的结果仍然为您应该再次检查代码的位置提供了非常有价值的提示。

监控内存消耗也可以为您提供进一步的提示;如果它超出合理的限制,那么您可能有内存泄漏。

你的具体例子:

第一个变体可能会产生内存泄漏,但不一定

Dictionary d1 = ...;
Dictionary d2 = createDic(d1, &n);

// now you could use both of d1 and d2
// however risk of double deletion if re-allocation failed;
// need to compare d1 and d2 for equality before freeing them

Dictionary d3 = ...;    // assume this is the sole pointer to d3
d3 = createDic(d3, &n); // if re-allocation succeeded last reference to
                        // old dictionary is lost -> memory leak

第二种变体避免了这种情况,但有另一个缺点:

Dictionary d1 = ...;
Dictionary d2 = createDic(d1, &n);

如果成功,指针d1 会失效,读取它会导致未定义的行为。因此,您还必须将其更新为新值。

总而言之,第二个变体应该会带来更少的麻烦,所以我更喜欢它。顺便说一句:如果您修改该变体以在成功返回之前删除旧字典,则相当于第一个变体......

【讨论】:

  • 所以在第一个变体中,如果我先做 free(dics) 然后 dics = temp 它不会引起任何问题吗?另外,我使用的是 W10,而 Valgrind 在我所见的 W10 上不可用
  • @someone 是的,确实。对于 valgrind:使用 valgrind windows 尝试您最喜欢的搜索引擎,您会找到像 here on SOvalgrind with WSL 这样的替代品。
猜你喜欢
  • 1970-01-01
  • 2016-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
  • 1970-01-01
  • 2013-02-03
相关资源
最近更新 更多