tags:

views:

113

answers:

2

I have two examples I have a question about. Let me explain via some code:

Question 1:

QStringList qsl(); // Create a list and store something in it
qsl << "foo";
QString test = "this is a test"; 
qsl = test.split(" ", QString::SkipEmptyParts); // Memory Leak?

What happens when I re-assign the qsl variable what happens to "foo" and the original data allocated on the first line?

Question 2:

class Foo
{
     QStringList mylist;
     void MyFunc(QStringList& mylist)
     {
           this->m_mylist = mylist;

     }

     void AddString(QString str)
     {
         mylist << str;
     }



}

int main()
{
    Foo f;
    QStringList *qsl = new QStringList();
    f.MyFunc(*qsl);
    delete qsl;
    f.AddString("this is a test"); // Segfault?
}

Here I'm passing a list by reference to a class which is then stored in said class. I then delete the original object.

It basically all comes down to what happens when you assign a QObject to a QObject. I assume a copy of the object is made, even if the object was passed in via reference (not via pointer of course, that would just be a pointer copy).

I also assume that something like QStringList performs a deepcopy...is this correct?

A: 

What happens when I re-assign the qsl variable what happens to "foo" and the original data allocated on the first line?

You can't reassign qsl to something else within the same scope.
Once it goes out of scope the memory will be reclaimed in it's destructor.
You can put different data into qsl, in which case it will replace "foo", more memory might be allocated if necessary

edit: eg. you can't have "QStringlist qsl;" Then in the same code block have "int qsl;"
You can replace the strings in qsl with a different list and the container will handle the memory for you

I also assume that something like QStringList performs a deepcopy

Yes, - actually it's a little more complicated, to save time/memory Qt will only do the copy when it needs to, ie when it changes. If you copy "a string" to lots of different string lists, Qt will just keep one copy and share it around, when one changes it will allocate a new copy for the changed one - it's called "copy on write" but happens automatically and you don't need to care.

Martin Beckett
"You can't reassing qsl to something else within the same scope."meaning I'll have a memory leak if I do? Because the compiler seems to let me do it.
Timothy Baldridge
Ahhh....so should I use the copy constructor then?
Timothy Baldridge
Your 2nd assignment of the split is fine, the stringlist will just delete (or reuse) the memory of "foo"
Martin Beckett
+1  A: 

Assigning to a QStringList variable works the same as assigning to any other variable in C++. For objects, the assignment operator of the object on the left is called to copy the content of the object on the right into the object on the left. Usually this does just a memberwise assignment:

struct A {
  int x;
  QString y;

  A& operator=(const A &other) {
    // do the assignment:
    x = other.x;
    y = other.y;

    return *this;
  }
};

The object on the left of the assignment "adapts itself" to contain the same things as the object on the right. There is no new object allocated, just the existing one is modified.

If the class is more complicated and for example contains pointers to dynamically allocated data (like it is probably is the case for QStringList), the assignment operator might be more complicated to implement. But this is an implementation detail of the QStringList class and you should not have to worry about that. The QStringList object on the left of the assignment will be modified to be equal to the object on the right.

In Question 2 you assign an object to a member variable, which causes the object in the member variable to be modified so that it contains the same things as the object that is assigned to it. That this other object later is deleted doesn't matter to the member variable.

Semantically this is the same as when assigning simple integers:

int i, j;
i = j;

The memory where i is stored is modified, so that it contains the same value as j. What happens to j later on doesn't matter to the value of i.

sth
Thanks, this was exactly the information I was looking for.
Timothy Baldridge