2d QList内存泄漏

时间:2011-02-01 00:12:33

标签: c++ qt qt4

我创建了这个2D Qlist。代码“有效”,但当我考虑更深入的语法时,它让我想知道这段代码是否会导致内存泄漏。

如果有人能够了解这段代码是否会导致内存泄漏,我会很高兴。如果是的话,为什么以及如何解决?

我的具体问题是代码注释中标记为Q1,Q2,Q3,Q4的问题。

另外,我应该如何从lszq2DList中销毁一些行,最终应该如何销毁 lszq2DList。

//The 2d data sructure. Each row will be a QStringList.
QList<QStringList> lszq2DList; 

//The variable "emptyTempList" is a concern to me.  
//Q1:: Isn't "emptyTempList" just a pointer to some allocated place in memory?  
//If so, I imagine it points to some data structure allocated in memory.
//Or does this not allocate anything?  I have a feeling it does not.
QStringList emptyTempList;   //I use it in my scheme to make a 2D data struct.

for(int i=0; i<3; i++){
    //Q2: Because I am in a loop and reusing the same pointer "emptyTempList", 
    //aren't i pointing to the same thing?
    //If I think about this, each item in my Qlist (each row) should be 
    //pointing to the same place in memory.  To whatever "emptyTempList"
    //points to.    
    //Of course, this is not the case.  What is really going on in line bellow?
    lszq2DList += emptyTempList;  //I'm no really pointing to anything am I?  

    QString szqTempString;  //Q3: Gets trashed when out of scope?
    for(int j=0; j<3; j++){
        szqTempString.clear();
        szqTempString = "jazz";

            //QString value gets copied into datastructure?
        lszq2DList[i] += szqTempString;  
    }
}


QStringList emptyTempList2;
emptyTempList2 += "blues";
emptyTempList2 += "blues";
emptyTempList2 += "blues";

//I'll add another row.
lszq2DList += emptyTempList2;  
//Q4: lszq2DList[3] does not point to emptyTempList2, right?
//Instead it copies all the strings 
//from to emptyTempList2 to lszq2DList[3], right?

2 个答案:

答案 0 :(得分:4)

QList,QStringList和QString都是“隐式共享”,基本上意味着“写入时复制”。例如:

QStringList someFunction() {
    QStringList list;
    QString str("Hello World!");

    for(int x = 0;x < 100; ++x) {
        list << str;
    }

    QStringList list2 = list;
    QStringList list3 = list;
    QStringList list4 = list;

    return list4;
}

QStringList list5 = someFunction();

毕竟你还只有字符串“Hello World!”在记忆中一次。您可以阅读更多相关信息Here。作为Qt类的一般规则,“从QObject继承的对象进入堆,否则它们进入堆栈”。有异常,但很少和隐式共享的类应该总是在堆栈上。

答案 1 :(得分:3)

我建议使用与valgrind或其他类似的东西来检查内存泄漏。

然而,当内存“泄漏”时,这意味着在使用后该内存根本没有释放,并且所有访问都已被删除。这实际上意味着在堆上分配了内存,但是没有任何东西可以访问它,所以它实际上是无用的内存。例如,当您使用“new”动态地将内存分配给指针时,必须“删除”以释放内存。我举一个例子。

char * ptr = new char;
ptr = NULL; // Memory leak
delete ptr; // This is useless since it no longer points to the memory location

然而,这是完全有效的

char * ptr = new char;
delete ptr;
ptr = NULL;

第一个泄漏的原因是因为你没有“删除”内存。由于在调用delete之前指针位置已更改为“NULL”,因此在将设置为NULL之前,它不知道在指针与关联的任何地址处释放内存。

但是,它看起来并不像你的代码会有任何内存泄漏(没有动态分配)。由于看起来所有变量都在堆栈上分配,系统会为您管理这个内存 - 一旦这些对象超出范围(如果在main()中,那么当程序退出时),它们将被弹出按系统排除堆栈。但是,假设QList没有泄漏。

修改

请记住,当您创建类的实例时,分配的内存位于堆栈上(内存在离开范围时立即释放),您无需担心。动态分配(使用new / delete分配/释放内存)存储在堆上(为了我们的目的,持久性内存)。因此,您不必担心没有动态分配的内存泄漏。

编辑2

关于使用堆与堆栈,尽可能使用堆栈。你需要管理的内存越少越好(并且你将会出现更少的错误)。就问题2而言,您没有使用指针。你正在做的是复制emptyTempList而不是重用它的内存位置(因为它不是指针)。您必须使用&运算符从对象中提取内存地址,因为它不是指针。

希望这有帮助!

的问候,
丹尼斯M。