[SOLVED] How to deallocate QVector<Type*>?



  • Hello Guys,

    I have a simply and probably nooby question. How to deallocate this Vector?
    @QVector<Type*> v;@

    Its enough to go out of scope? But what's with the pointers within the Vector? Will they deleted to?


  • Moderators

    No, the objects that the pointer points to will continue to be alive. If you need to delete them, you have to do it yourself, for example:
    @
    foreach (Type *type, v) {
    delete type;
    }
    @



  • Okay, I guess. Thanks!



  • Oh, I got one more problem. I don't know why but the code you posted doesn't work. Got a runtimeerror. I also tried a "normal" for loop with
    @delete v.at(i)@

    in block.


  • Moderators

    [quote author="heiopei" date="1413887346"]Oh, I got one more problem. I don't know why but the code you posted doesn't work. Got a runtimeerror. I also tried a "normal" for loop with
    @delete v.at(i)@

    in block. [/quote]

    I actually suspected that would be the case ;-) Good you've solved it on your own, congratulations.



  • Nono you missunderstood me. It doesn't work with this code
    @
    for(qint32 i = 0; i < v.size(); i++)
    {
    delete v.at(i);
    }
    @


  • Moderators

    Ah, ok. Try this:
    @
    for(int i = 0; i < v.size(); i++)
    {
    delete v.takeAt(i);
    }
    @



  • Thanks I didn't know takeAt. Now there occurs no error, but it seems my Vector won't delete completly. Bescause before the loop the size of Vector is 18 and after its 9.

    edit:
    Why I just can't use the clear function?

    bq. Removes all the elements from the vector and releases the memory used by the vector.



  • clear method doesn't call delete on the pointers that are in the container, it only clear the memory of the container, but in the container you have addresses to memory stored somewhere else and that memory should be freed by calling delete on that pointer, so that you don't create a memory leak.

    You can use "qDeleteAll":http://qt-project.org/doc/qt-4.8/qtalgorithms.html#qDeleteAll to delete the pointers and than use clear to empty the container.

    LE: also you need to make sure that the pointers are to heap allocated memory, if you call delete with an address of a variable allocated on stack you get a crash.



  • Mhm still get an error. :(

    @
    qDeleteAll(v.begin(), v.end());
    v.clear();
    @

    also edit:
    Well the Objects in Vector should be allocated at heap because its done with new....



  • Maybe the pointers point to stack allocated objects, you can show us how you fill the vector or better use a debugger to see what happens.
    Also the vector might be used from another thread or it may be an error in Type's desctructor that causes a crash.



  • But its weird that when i use this code:
    @
    for(int i = 0; i < v.size(); i++)
    {
    delete v.takeAt(i);
    }
    @

    The half of Vector is deleted...


  • Moderators

    Every time you call takeAt, it removes an item from the vector, so size() gets smaller, but your i is getting bigger ;-)



  • [quote author="heiopei" date="1413890181"]...
    The half of Vector is deleted...[/quote]
    Then you might have an invalid pointer in there, check if one of the pointers is not previously deleted and left in the container, calling delete twice on the same pointer (without new in between) is undefined behavior and will crash your application.

    We can't really guess what happens, you need to debug your application, or try to replicate the behavior in an small piece of code that you post here so that we can see the issue.



  • I wrote this code and used with another Vector in my programm.
    @
    while(v2.size() > 0)
    {
    delete v2.takeAt(0);
    }
    @

    It seems to work, because after the loop the size is 0. Do you think this snippet is okay?

    Actually the snippet doesn't work fine with my first Vector (in this thread called v). At the size of 2 I get an error. Maybe there is really an inavlid pointer....its weird... :(


  • Moderators

    This indeed seems like an invalid pointer in your v vector.

    If the pointer type inherits from QObject and has a parent, then maybe the parent has already deleted it?



  • Ahhhhhh, I finally found the error. You were both right. I deleted exactly one object from the Vector at another Place in my program. Thank you very much. I think I understand the complete topic with allocat and deallocate much more!

    But I have one little question. I deleted the object with delete and after that I set it to 0. I thought with this procedure I am avoiding the problem with invalid pointer. Whats the behavior to set the object to 0?


  • Moderators

    [quote author="heiopei" date="1413965842"]But I have one little question. I deleted the object with delete and after that I set it to 0. I thought with this procedure I am avoiding the problem with invalid pointer. Whats the behavior to set the object to 0?[/quote]

    In C++, a pointer is in reality only an integer value (a number) that is the memory address of the object. So, after you delete it, the object is destroyed (using it's destructor), and memory freed, but that pointer remains unchanged - it's still just a number.

    When you set a pointer to 0, that number changes to 0. Nothing other happens. So, if you want to verify (somewhere else in your code) that the object is deleted, you can then simply check if it is equal to 0. The compiler will not do it for you. If you attempt to delete a pointer set to 0, your program will crash at runtime. If you try to delete a pointer to an already deleted object, it will also crash.

    So the usual way of doing things (apart from QObjects, which manage their memory automatically) is to delete a pointer, and set it to 0. Then, everywhere else the pointer is used, a check is performed, like so:
    @
    if (somePointer) {
    // pointer is assumed to be valid, because it is not zero. Of course, if the object was deleted, it would still crash
    // if you tried doing something to that pointer
    } else {
    // pointer is zero. Better not do anything with it
    }
    @



  • Okay, I see its very helpfull. Thanks for your reply and help. :-)


  • Moderators

    I've edited my reply and explained the topic a bit more thoroughly. Enjoy :-)



  • General programming tip: if you modify a container that you access by index (such as a list or a vector), iterate over it from back to front. That will avoid problems such as the one you encountered here. So:

    @
    for (int i(myList.count()-1); i >= 0; i--) {
    delete myList.takeAt(i);
    }
    @

    However, for clearing a Qt container containing pointers, I'd really recommend just calling:
    @
    qDeleteAll(myList);
    myList.clear();
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.