首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >删除列表分配的内存

删除列表分配的内存
EN

Stack Overflow用户
提问于 2012-12-11 19:31:02
回答 1查看 2.3K关注 0票数 0

看一下下面的代码。在这段代码中,在执行开始时,内存使用量是1020K。但是在执行结束时,内存使用量是1144K。谁能帮我找出内存泄露的原因。如果调用func()五次,内存使用量将分配给1500K+。如果我们不使用列表,内存使用量不会增加。

代码语言:javascript
运行
复制
void func();

int _tmain(int argc, _TCHAR* argv[])
{
    func();
    return 0;
}

void func()
{
    list<char*> list1;
    list<char*>::iterator iter;
    char* val;
    for(int i=0; i<100000; i++)
    {
        val = new char[20];
        for(int j=0; j<20;j++)
        {
            val[j] = 'A';
        }
        val[19] = '\0';
        list1.push_back(val);
    }

    iter = list1.begin();
    for(int k=0; k<100000;k++, iter++)
    {
        delete[] *iter;
        *iter = NULL;
    }
    val = NULL;

    list1.clear();
    list1.empty();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-11 20:06:10

我在这里看不到内存泄漏,,但是我确实看到了很多非常糟糕的代码。

我在你的代码中看到了一些提示,你是在Windows下运行的,当我凝视我的水晶球时,我想我看到你在检查任务管理器来检测内存泄漏。使用任务管理器检测内存泄漏就像使用大刀做手术一样。TM也许能够给你一个提示,系统中可能存在大量的内存泄漏,但它离你的程序太远了,太粗糙了,不能确定。您需要使用专门用于该工作的工具,而不是使用TM来确定是否存在内存泄漏。Visual Studio has such a tool内置。

当我在您的代码中使用这些内置工具时:

代码语言:javascript
运行
复制
#include <cstdlib>
#include <list>
using std::list;

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>


void func();

int main(int argc, char* argv[])
{
    func();
    return 0;
}

void func()
{
    list<char*> list1;
    list<char*>::iterator iter;
    char* val;
    for(int i=0; i<100000; i++)
    {
        val = new char[20];
        for(int j=0; j<20;j++)
        {
            val[j] = 'A';
        }
        val[19] = '\0';
        list1.push_back(val);
    }

    iter = list1.begin();
    for(int k=0; k<100000;k++, iter++)
    {
        delete[] *iter;
        *iter = NULL;
    }
    val = NULL;

    list1.clear();
    list1.empty();

    _CrtDumpMemoryLeaks();
}

...I请参阅:

代码语言:javascript
运行
复制
Detected memory leaks!
Dumping objects ->
{142} normal block at 0x00000000000778C0, 24 bytes long.
 Data: < x       x      > C0 78 07 00 00 00 00 00 C0 78 07 00 00 00 00 00 
{141} normal block at 0x0000000000077840, 16 bytes long.
 Data: <(       h       > 28 F7 1A 00 00 00 00 00 68 F7 1A 00 00 00 00 00 
Object dump complete.

有两个内存泄漏报告,总共40个字节,所以这里没有广泛的内存泄漏。此外,这些可能是误报,报告CRT的静态内存分配等情况,应该忽略。

然而,正如我所说的,我确实看到了很多非常糟糕的代码。这不是造成内存泄漏的原因,但它们很容易出现在真正的代码中。

  1. You使用了大量的 。例如使用for(int i=0; i<100000; i++),你应该迭代列表(for( list<char*>::iterator it = list1.begin(); it != list1.end(); ++it)),或者至少询问列表中有多少元素正在使用动态分配/释放。在你确实需要动态分配的情况下,你应该使用RAII,但只要有可能,就应该避免动态分配。在您的例子中,您应该有一个使用手写循环的list<std::string> instead.
  2. You,在您可以使用标准库提供的算法的地方使用list<char*>,而不是list<std::string>。你从未写过的代码是最可靠的代码。使用copytransform.

代替内部循环初始化字符数组,只需执行std::string s(20,'A'),而不是外部循环设置每个列表成员

编辑以下是您的函数的重新设计版本,它解决了我上面提到的一些问题:

代码语言:javascript
运行
复制
#include <string>
using std::string;
#include <algorithm>
using std::generate_n;
#include <iterator>
using std::back_inserter;

void func()
{
    static const size_t NumStrings = 10000;
    typedef list<string> strings;

    // Populate the list
    strings list2;
    generate_n(back_inserter(list2), NumStrings, []() -> string
    {
        static const size_t NumChars = 19;
        static const char InitChar = 'A';
        return string(NumChars, InitChar);
    });

    // Clear the list
    list2.clear();

    // Done
    _CrtDumpMemoryLeaks();
}

generate_n的调用使用C++11 lambda,但可以很容易地重构为使用函数器或其他完全的东西。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13819451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档