QSharedPointer Usage Found



  • Found that if take object out of shared pointer, and put it into a new shared pointer, will cause crash.
    The following code will crash after j=1, i=0.
    Is is expected?

    I wrote a page here, with pictures, may be easier to see.
    link text

    Thanks

    #include "mainwindow.h"
    #include <QApplication>
    #include <QDebug>

    class Animal
    {
    public:
    Animal(int id){this->id = id;}
    virtual ~Animal(){}
    int id;
    };
    class Dog:public Animal
    {
    public:
    Dog(int id):Animal(id){}
    ~Dog(){}
    int legs;
    };

    int main(int argc, char *argv[])
    {

    QList<QSharedPointer<Animal>> animals;
    for(int i=0; i<10; i++){
        animals.append(QSharedPointer<Animal>(new Dog(i)));
    }
    for(int j =0; j < 100; j++){
        for(int i=0; i< 10; i++){
            qDebug() << "j=" << j << "i=" << i;
            // take out data and assign it to a new shared pointer
            auto p = QSharedPointer<Animal>(animals[i].data());
        }
    }
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
    

    }
    Hope it helps



  • auto p = QSharedPointer<Animal>(animals[i].data());

    Above code means that p is going out of scope.
    and thus pointer will be deleted.

    Documentation clearly states:

    T * QSharedPointer::data () const
    Returns the value of the pointer referenced by this object.

    Note: do not delete the pointer returned by this function or pass it to another function that could delete it, including creating QSharedPointer or QWeakPointer objects.



  • @alex_malyu However, docs also say:
    "QSharedPointer will delete the pointer it is holding when it goes out of scope, provided no other QSharedPointer objects are referencing it."

    As far as I see, the list still holds a shared pointer to all objects, so none of them should be deleted.


  • Moderators

    There's no magic to shared pointers. The pointer returned by data() does not carry information about the original shared pointer (how could it?). Your code creates two shared pointers with reference count 1. If you want to really share the data use copy constructor or operator= e.g.

    auto p = animals[i];
    

    This will cause the p to have ref count 2 and thus it will not delete the data when p goes out of scope.



  • Agree with Asperamanca said.
    Chris Kawa, Yes, we could use second shared pointer as you said. But wonder why my way will crash.



  • @sharethl Chris explained it. You create two shared pointers, which don't know anything about each other. The pointer "p" runs out of scope, believes it held the last instance to the object and deletes it. On the next loop, you attempt to create a shared pointer from a deleted object.


  • Moderators

    @Asperamanca Just to clarify - creating another shared pointer from the deleted pointer is ok. Well.. not really ok, but it will not cause a crash. The crash will occur when the original shared pointer (the one in the array) or the new one go out of scope, at which point they would call delete on an invalid pointer.



  • Yes, Chris. That is right, once use shared pointer, never delete it.

    This is the QSharedPointer.data() document in help. see content in []

    do not delete the pointer returned by this function or pass it to another function that could delete it, [including creating QSharedPointer or QWeakPointer objects.]


Log in to reply
 

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