Use delete on allocated objects without new?

Asked

Viewed 425 times

3

Hello, from always until today in my c++ projects with Qt, I have always used delete objects only when I dynamically allocate them with the operator new, But in my last project that was relatively large, I started to feel a difference in performance as it went along. The project in question fired images of a camera on the screen, and over time began to get very slow its sequence of frames, even dividing its process into a Qtimer. As my progeny has many so-called objects, I began to think about the question of memory liberation. My question is, objects allocated in the stack, that is, a non-dynamic object, must have their memory released at some point?

Example of non-dynamic object I refer to:

void MyClass::functionExample(){

    AnotherClass obj;
    obj.setData(1);

}

Normally I use delete or call the class destructor only for this situation:

void MyClass::functionExample(){

    AnotherClass *obj = new AnotherClass();
    obj->setData(1);
}

In the case of objects declared as attribute private of my class, should I also release memories of these objects? Thank you from now.

  • 1

    The ideal is not to use delete, is to play the pointer inside a "smart Pointer". My last major C++ project scanned the use of "delete" and wouldn’t build it if it found a.

2 answers

3


Important remark:

In this answer I use freely the term "static" allocation and "dynamic" to refer respectively to the allocation of data in the stack and no heap. I call stack allocation "static" because it is kind of unchanging (it is done at the beginning of the program), and the allocation in the heap of "dynamics" because the control is more directly in the hand of the programmer.

For example, Mr @Maniero, commented very well the following to that respect:

"I use a different terminology, for me static allocation is that made in advance and valid for all the execution of the application, therefore do not need to allocate. Stack allocation, append the name induce to be something static by similarity, it is not a static allocation, it is automatic. The allocation of the entire stack is static, but not its objects. I think the terminology used is wrong and gives a misconception, at least for those who understand the subject. For whom does not understand will even understand, but the wrong. So the confusion."

And fellow @Jose X. also commented very well in that regard:

"This matter goes far... here and here (the text from the OS points to the Wikipedia link). I just wanted to give one more example: a non-Static and nonpointer member of a class that is instantiated in the heap... truth is allocated in heap, not stack."

Actually, perhaps the term "automatic allocation" is more appropriate to avoid confusion. I made this observation because I thought she was important, although the focus of the answer was not that necessarily.

Statically allocated objects (i.e., in the stack) exist in the scope in which they were created. When this scope ends, they are automatically removed by the compiler. Thus, in your code...

void MyClass::functionExample(){

    AnotherClass obj;
    obj.setData(1);

}

...the instance of obj will exist only within the method functionExample. When this method is finished, this instance will be deleted automatically (and the destructor, if it exists, will be invoked).

Unlike the previous ones, dynamically allocated objects (i.e., in the heap) exist until they are explicitly destroyed (by the programmer in general). When memory is allocated many times in heap and is not released by error, it occurs what is called memory leakage (memory Leak), which causes even a gradual reduction in the performance of the system by the excessive use of resources (although it is not the only potential cause of poor performance).

So in your code...

void MyClass::functionExample(){

    AnotherClass *obj = new AnotherClass();
    obj->setData(1);
}

There is a memory leak. The variable obj is a pointer to an instance of AnotherClass. It, by itself, is a statically allocated variable (in the stack - do not confuse with a variable declared as static) and therefore exists only within the scope of the method functionExample. Using the operator new, you create a new instance of AnotherClass (allocating memory for such) and saves the address of that memory in the variable obj. When the method functionExample ends, this variable is deleted, and since you no longer have the address reference that was allocated you no longer have a way to release that memory that remains "lost" in the heap until the entire program is finished.

Note that Qt has some features to automatically manage the memory of objects inherited from QObject. When you create a widget, for example, you can specify as a parameter the pointer to an instance of another widget (QWidget*) that will be the "father" of that object. That parent object will automatically destroy all your children when it is itself eliminated.

I don’t know if that was the case, since you didn’t quote from your class AnotherClass inherit from QObject, but even if it was the leak still exists because you did not pass such parameter (usually this to indicate that the actual object is the father of the one being created).

  • Thank you, you’ve clarified my question. You said that an instance created from an object as an attribute of a class will exist as long as the class is used. In case of multiple object calls, does the memory release apply in this case? even the class attributes are not dynamic, it is recommended that I release them from memory manually?

  • 1

    I did say that, but only for attributes that are non-dynamically allocated (that is, they are not pointers that you used new). Yes, the memory release is equal, because each object will have its own scope.

  • 2

    The term dynamic allocation is actually used a lot. Static does not usually see. The stack is static, but the objects within it that are the allocations that are referenced in the response are made on demand. They are two concepts of allocation. Is it true that I’ve seen different terms (I think activation, I don’t know) for the objects that are placed in the stack, but everyone talks about allocating and is understood. So much so that the term automatic allocation means that you can use what is already allocated (in the sense of reserved) in memory. The allocation is done simply, without request. It is confusing to have 2 steps

2

You should only use delete for objects allocated with new. Dot.

  • Thank you for answering, can you tell me if static allocated objects need to be released from memory somehow?

  • 1

    Yuri, the answer is: no, they don’t. Static objects are deleted when they leave the scope (when the function ends, for example).

  • Thank you! One last thing, even applies if the non-dynamic object is an attribute of the class, and I use it later in my class?

  • I answered. Take a look at the answer. And yes, a static object that is attribute of a class will exist as long as the instance of that class (which contains it) exists.

  • @Luiz Vieira: his comment was confused... static of a class does not depend on the existence of any instance of the class;

  • Truth Jose. Sorry. I meant static allocation. Not explicitly stated as static. Thanks for the warning. :)

  • @Luiz Vieira I think he was still confused...I imagine that by "static allocation" you mean that the object was not created in heap (via new), but my impression is that "static allocation" does not apply in the case

  • @Joséx. What case? Now I didn’t understand what you meant. PS: yes, by "static allocation" that’s what I meant.

  • 1

    Important detail: new/ delete call the constructor/destructor of the object before/after releasing the memory allocated by it, while the functions of the malloc()/ free() do not. -- think about what can happen if you mix the two things.

  • 1

    I use a different terminology, for me static allocation is the one done previously and is valid for all the execution of the application, so you do not need to release. The allocation in stack, though the name induce to be something static by similarity, it is not a static allocation, it is automatic. The allocation of all the stack is static, but not its objects. I think the terminology used is wrong and gives a wrong understanding, at least for those who understand the subject. For those who do not understand will understand, but the wrong. That’s why the confusion.

  • I don’t think you should even use delete, nor new, point :D

  • @bigown "In real life" is virtually impossible not to use new/delete in any non-trivial application. Fortunately from the C++11 the smart pointers improved a lot, and as a result the need to use "raw" new/delete decreased a lot as well. But the existing corporate systems today, filled with new/delete, will continue to exist for a long time yet...

  • @bigown Very well noted. I will take the liberty of copying the comment to the body of the answer, ok? :)

  • 1

    @Luizvieira only if you pay royalties :And I got a slip.

  • @Okay, I got it. rs

  • 2

    This subject goes far...take a look here http://stackoverflow.com/questions/8385322/difference-between-static-memory-allocation-and-dynamic-memory-allocation and here https://en.wikipedia.org/wiki/Static_variable (the text of the OS points to the Wikipedia link). I just wanted to give one more example: a member not-Static and non-pointer of a class that is instantiated in the heap....

  • Very well noted, @Joséx. :) I also added this comment to the body of my reply, ok?

Show 12 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.