Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. [SOLVED] memory deallocation,is there a nicer way to do that?
Qt 6.11 is out! See what's new in the release blog

[SOLVED] memory deallocation,is there a nicer way to do that?

Scheduled Pinned Locked Moved C++ Gurus
24 Posts 6 Posters 29.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    terietor
    wrote on last edited by
    #1

    Hello,

    I have a pointer and i want to be deleted after the scope runs out,so I use the QScopedPointer.
    The point is that this doesn't work.(I understand why it doesn't).

    @QScopedPointer<const char*> key = static_cast<const char *> something()@

    so in order to delete the pointer i did this

    @delete key@

    Is there a nicer way to do this???

    thanks in advance

    terietor.gr

    1 Reply Last reply
    0
    • K Offline
      K Offline
      koahnig
      wrote on last edited by
      #2

      Yes, nothing !!

      the documentation sais in the first line:
      [quote]The QScopedPointer class stores a pointer to a dynamically allocated object, and deletes it upon destruction.[/quote]

      [edit] Sorry, hit the wrong button.

      It is sort of a shared pointer (see [[doc:QSharedPointer]]).

      Vote the answer(s) that helped you to solve your issue(s)

      1 Reply Last reply
      0
      • R Offline
        R Offline
        rokemoon
        wrote on last edited by
        #3

        After the scope runs out QScopedPointer call destructor him self, so you don't need to call
        @delete key;@
        As koahnig says you should put to QScopedPointer dynamically allocated object, so
        @SomeClass * something() { return new SomeClass(); }@
        @QScopedPointer<SomeClass> key(something());@

        1 Reply Last reply
        0
        • R Offline
          R Offline
          rokemoon
          wrote on last edited by
          #4

          Just forget, QScopedPointer is a template class so you need declare just type and this type will be a pointer inside class. In your case obtained QScopedPointer and type is: @const char **.@
          Sorry for my english :-)

          1 Reply Last reply
          0
          • T Offline
            T Offline
            terietor
            wrote on last edited by
            #5

            First of all,thank you for answers.

            Yes you have right.
            @const char something; @

            is not an object.

            The point is that i can't do

            @delete key@

            because in the last line of my scope the value of key is being returned.

            @return key;@

            Do you have any idea how i can delete the key?

            terietor.gr

            1 Reply Last reply
            0
            • R Offline
              R Offline
              rokemoon
              wrote on last edited by
              #6

              Can you give us more code? Where you want delete and what key, write all algo

              1 Reply Last reply
              0
              • T Offline
                T Offline
                terietor
                wrote on last edited by
                #7

                here,

                @QVariant Something() {
                const char* key = m_topEntries.at(parent.row());
                return key;
                }@

                I want to delete the key,eg

                @delete key;@

                but how can i do it when i need it in the last line of my scope?

                terietor.gr

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  rokemoon
                  wrote on last edited by
                  #8

                  If you have there @const char* key = m_topEntries.at(parent.row());@ a dynamically allocated object so for example you can do like this:
                  @
                  QVariant Something() {
                  const char* key = m_topEntries.at(parent.row());
                  return qVariantFromValue(QByteArray(key));
                  }

                  QVariant variant(Something());
                  if (variant.type() == QVariant::ByteArray) {
                  QByteArray byteArray(variant.toByteArray());
                  //do something

                  //and at the and
                  delete byteArray().data();
                  }
                  @

                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    rokemoon
                    wrote on last edited by
                    #9

                    More elegantly you can do like this:
                    register sharedPointer somewhere
                    @
                    Q_DECLARE_METATYPE(QSharedPointer<const char>);
                    @
                    then
                    @
                    QVariant Something() {
                    QSharedPointer<const char> keyPointer(m_topEntries.at(parent.row()));
                    return QVariant().setValue(key));
                    }

                    QVariant variant(Something());
                    if (variant.canConvert<QSharedPointer<const char> >()) {
                    QSharedPointer<const char> keyPointer(variant.value<QSharedPointer<const char> >());
                    //do something
                    }
                    @
                    So when variant goes out if scope it's automaticly delete your key.
                    Try it I don't test this.

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      lgeyer
                      wrote on last edited by
                      #10

                      A few annotations:

                      • m_topEntries.at(...) does obviously return a pointer to an already existing object and does not allocate any new memory. There is no need to call delete key unless you want to delete the object the pointer does point to (key is created on the stack and does automatically vanish after it goes out of scope).
                      • If so, you should use takeAt() instead of at() or at least reset the item to null after you have deleted the object otherwise your container will contain a dangling pointer.
                      • I assume that the objects stored within the m_topEntries container are created with new, otherwise you must not call delete.
                      • QScopedPointer is not the object itself - it is a pointer to an object. It automatically destroys (read, calls delete) the object it points to at the time QScopedPointer itself is destroy (for example when created on the stack and going out of scope).
                      • QScopedPointer wraps a pointer for the given type, thus it has to read QScopedPointer<const char> instead of QScopedPointer<const char*>.
                      • When using a QScopedPointer to delete the object make sure that the object is removed from the container as well (see #2).
                      • If it is about storing strings you should go for QString instead of const char*. QString supports unicode and is implicitly shared, which means that it is automatically destroyed as soon as not referenced anymore.
                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        rokemoon
                        wrote on last edited by
                        #11

                        [quote author="Lukas Geyer" date="1313262099"]A few annotations:

                        • m_topEntries.at(...) does obviously return a pointer to an already existing object and does not allocate any new memory. There is no need to call delete key unless you want to delete the object the pointer does point to (key is created on the stack and does automatically vanish after it goes out of scope).
                        • If so, you should use takeAt() instead of at() or at least reset the item to null after you have deleted the object otherwise your container will contain a dangling pointer.
                        • I assume that the objects stored within the m_topEntries container are created with new, otherwise you must not call delete.
                        • QScopedPointer is not the object itself - it is a pointer to an object. It automatically destroys (read, calls delete) the object it points to at the time QScopedPointer itself is destroy (for example when created on the stack and going out of scope).
                        • QScopedPointer wraps a pointer for the given type, thus it has to read QScopedPointer<const char> instead of QScopedPointer<const char*>.
                        • When using a QScopedPointer to delete the object make sure that the object is removed from the container as well (see #2).
                        • If it is about storing strings you should go for QString instead of const char*. QString supports unicode and is implicitly shared, which means that it is automatically destroyed as soon as not referenced anymore.[/quote]
                          Lukas you are the man :-) with my English I've afraid wrote such explanation.
                        1 Reply Last reply
                        0
                        • T Offline
                          T Offline
                          terietor
                          wrote on last edited by
                          #12

                          [quote author="Lukas Geyer" date="1313262099"]A few annotations:

                          • m_topEntries.at(...) does obviously return a pointer to an already existing object and does not allocate any new memory. [/quote]

                          correct :)

                          [quote](key is created on the stack and does automatically vanish after it goes out of scope).[/quote]

                          I understand that everything that is allocated in the stack that is being deleted automatically when it goes out of scope.
                          But why const char* is allocated in stack and not in the heap?
                          Pointer are allocated on the heap.But not this one.It has to do something with the arrays but i don't understand what.

                          [quote]* If it is about storing strings you should go for QString instead of const char*. QString supports unicode and is implicitly shared, which means that it is automatically destroyed as soon as not referenced anymore.[/quote]

                          This is a whole different story.
                          I am using the libs of an open source project,which is using the const char* instead of QString.Personally like you i prefer the QString.

                          thank you for your help!

                          terietor.gr

                          1 Reply Last reply
                          0
                          • L Offline
                            L Offline
                            lgeyer
                            wrote on last edited by
                            #13

                            [quote author="Giorgos Tsiapaliwkas" date="1313297784"][quote author="Lukas Geyer" date="1313262099"](key is created on the stack and does automatically vanish after it goes out of scope).[/quote]
                            I understand that everything that is allocated in the stack that is being deleted automatically when it goes out of scope.
                            But why const char* is allocated in stack and not in the heap?
                            Pointer are allocated on the heap. But not this one.It has to do something with the arrays but i don't understand what.[/quote]

                            No. A pointer and the object it points to are two different things. Both may exist on the stack or on the heap. A pointer is usually a variable on the stack pointing to an object on the heap (or the stack).

                            As a rule of thumb every single variable (including pointers) exists on the stack except those beeing on the right side of new. Only those created on the heap must be deleted using delete - those on the stack must not be deleted!

                            @
                            void foobar()
                            {
                            int intVariable = 0; // variable of type "int" created on the stack named "intVariable"
                            float floatVariable = 0; // variable of type "float" created on the stack named "floatVariable"

                            int* intPointer = 0;                    // variable of type "pointer to int" created on the stack (not heap) named "intPointer"
                            float* floatPointer = &floatVariable;   // variable of type "pointer to float" created on the stack (not heap) named "floatPointer"
                                                                    // pointing to an object on the stack (not heap)
                            
                            QObject* objectPointer = new QObject;   // there are two things created here:
                                                                    // - a variable of type "pointer to QObject" created on the stack pointing to an object on the heap 
                                                                    // - an object of type QObject created on the heap  
                            
                            QObject* anotherPointer = objectPointer;   // variable of type "pointer to QObject" created on the stack pointing to the same object on the heap as "objectPointer" does named "anotherPointer"
                                                                       // there is no (!) object on the heap created here
                            
                            // when leaving the function now, all of the six variables created on the stack will go out of scope
                            // but the object on the heap persists
                            
                            delete objectPointer;   // the object objectPointer points to is deleted from heap, but the pointer to it "objectPointer" still exists on the stack
                                                    // "objectPointer" and "anotherPointer" are now both invalid, because they point to a location in memory where no object exists
                            

                            }
                            @

                            [quote author="Giorgos Tsiapaliwkas" date="1313297784"]I am using the libs of an open source project,which is using the const char* instead of QString.Personally like you i prefer the QString.

                            thank you for your help![/quote]

                            QString can be used to encapsulate plain old char* strings. Just take a look at "QString":http://doc.qt.nokia.com/latest/qstring.html.

                            1 Reply Last reply
                            0
                            • G Offline
                              G Offline
                              giesbert
                              wrote on last edited by
                              #14

                              [quote author="Lukas Geyer" date="1313317669"]
                              QString can be used to encapsulate plain old char* strings. Just take a look at "QString":http://doc.qt.nokia.com/latest/qstring.html.[/quote]

                              Not really, QString always is unicode, never ASCII. If you want to encapsulate char* use QLatin1String.

                              Nokia Certified Qt Specialist.
                              Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                              1 Reply Last reply
                              0
                              • T Offline
                                T Offline
                                terietor
                                wrote on last edited by
                                #15

                                [quote author="Lukas Geyer" date="1313317669"][quote author="Giorgos Tsiapaliwkas"
                                @
                                void foobar()
                                {
                                int intVariable = 0; // variable of type "int" created on the stack named "intVariable"
                                float floatVariable = 0; // variable of type "float" created on the stack named "floatVariable"

                                int* intPointer = 0;                    // variable of type "pointer to int" created on the stack (not heap) named "intPointer"
                                float* floatPointer = &floatVariable;   // variable of type "pointer to float" created on the stack (not heap) named "floatPointer"
                                                                        // pointing to an object on the stack (not heap)
                                
                                QObject* objectPointer = new QObject;   // there are two things created here:
                                                                        // - a variable of type "pointer to QObject" created on the stack pointing to an object on the heap 
                                                                        // - an object of type QObject created on the heap  
                                
                                QObject* anotherPointer = objectPointer;   // variable of type "pointer to QObject" created on the stack pointing to the same object on the heap as "objectPointer" does named "anotherPointer"
                                                                           // there is no (!) object on the heap created here
                                
                                // when leaving the function now, all of the six variables created on the stack will go out of scope
                                // but the object on the heap persists
                                
                                delete objectPointer;   // the object objectPointer points to is deleted from heap, but the pointer to it "objectPointer" still exists on the stack
                                                        // "objectPointer" and "anotherPointer" are now both invalid, because they point to a location in memory where no object exists
                                

                                }
                                @
                                [/quote]

                                This one gives the answer to my question!

                                Thanks a lot :)

                                So when one pointer is not being followed by the new keyword,then there is no need to use the delete keyword.Correct?

                                P.S.:sorry for my late resonse but here (in my country) we had a big celebration and i was away from my pc.

                                terietor.gr

                                1 Reply Last reply
                                0
                                • L Offline
                                  L Offline
                                  lgeyer
                                  wrote on last edited by
                                  #16

                                  [quote author="Giorgos Tsiapaliwkas" date="1313517268"]
                                  So when one pointer is not being followed by the new keyword,then there is no need to use the delete keyword. Correct?[/quote]

                                  Short answer. Yes.

                                  Long answer. Basically every single variable is created on the stack, besides those explicitly created on the heap using the new keyword. Only those created on the heap must be explicitly deleted using delete (everything else must not be deleted). When using new, only the object on the right side of new is created on the heap.

                                  new and delete can be seen as ordinary functions, which just reserve a free block of memory. To access this block of memory one has to know where in memory this block has been reserved. And this is what the new "function" returns - the address of the block of memory it has just reserved. This return value is usually stored in a local variable (created on the stack) called a pointer.

                                  Pointers are an incredible powerful feature of the C / C++ languages, although they are sometimes a bit hard to understand. One essential thing to understand is that the pointer itself and the bit of memory it points to are two different things.

                                  Fundamental knowledge of how computers work (and how memory does work) is a good start if one wants to understand how pointers work. Fortunately "Google":http://www.google.com/search?q=c+++pointers has tons of answers on that.

                                  1 Reply Last reply
                                  0
                                  • T Offline
                                    T Offline
                                    terietor
                                    wrote on last edited by
                                    #17

                                    After a little googling i found that if inside in a method there is
                                    @something* foo() {
                                    return new something;}@

                                    and then if i do

                                    @something *a = foo();@

                                    that i have to use the delete keyword,

                                    @delete a;@

                                    So,in this situation

                                    @class SidebarTableWidget : public QTableWidget
                                    {
                                    Q_OBJECT

                                    public:
                                    SidebarTableWidget(Qt::DockWidgetArea location, QWidget *parent = 0);
                                    ~SidebarTableWidget();
                                    QScrollBar *m_horizontalSB;
                                    };
                                    SidebarTableWidget::SidebarTableWidget(Qt::DockWidgetArea location, QWidget *parent){
                                    m_horizontalSB = horizontalScrollBar();
                                    //m_horizontalSB doesn't create a memleak.Correct?
                                    }@

                                    I guess that Qt handles this and it doesn't create a mem leak.correct?

                                    terietor.gr

                                    1 Reply Last reply
                                    0
                                    • R Offline
                                      R Offline
                                      rokemoon
                                      wrote on last edited by
                                      #18

                                      [quote author="Giorgos Tsiapaliwkas" date="1313574152"]
                                      I guess that Qt handles this and it doesn't create a mem leak.correct?
                                      [/quote]
                                      Yes it's "correct":http://doc.qt.nokia.com/latest/qobject.html#QObject if you give parent to widget

                                      1 Reply Last reply
                                      0
                                      • T Offline
                                        T Offline
                                        terietor
                                        wrote on last edited by
                                        #19

                                        [quote author="rokemoon" date="1313574984"]
                                        if you give parent to widget
                                        [/quote]

                                        Do you mean this?

                                        @SidebarTableWidget *a = new SidebarTableWidget(this);@

                                        terietor.gr

                                        1 Reply Last reply
                                        0
                                        • L Offline
                                          L Offline
                                          lgeyer
                                          wrote on last edited by
                                          #20

                                          There are multiple ways how an object can become the parent of another. Passing a parent object to a constructor of another object is one of it, yes.

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved