C allows for the creation and destruction of objects in various contexts. Understanding when and how these operations occur is crucial for effective resource management and avoiding memory leaks.
Automatic Objects (Local Variables):
Automatic objects are destroyed in reverse order of their definition when control flow exits their scope (functions, blocks, etc.). If an exception is thrown during function execution, automatic objects are destructed before the exception is propagated. Important note: Destructors of automatic objects should never throw exceptions.
Non-local Static Objects (Global Variables):
Static objects defined at namespace scope are destructed after main() execution, in reverse order of their definition. If an exception leaves the destructor of a static object, std::terminate is called.
Local Static Objects:
Static objects defined within functions are constructed when control flow enters their definition for the first time. They are destructed after main() execution, in reverse order of their definition. Again, their destructors should not throw exceptions.
Base Class Subobjects and Member Subobjects:
Member subobjects are destructed in reverse order of their definition, followed by base class subobjects in order of the base-specifier-list. Exceptions during construction of a subobject lead to the destruction of all previously constructed subobjects before propagating the exception. The destructor is responsible for releasing resources such as files, sockets, etc.
Array elements are destructed in descending order. Exceptions during element construction lead to the destruction of previously constructed elements before propagating the exception.
Temporary objects (created during prvalue expression evaluation) are destructed when the full expression is evaluated. Exceptions during temporary object evaluation lead to proper destruction of previous temporaries. If a local reference is initialized with a prvalue, the temporary object's lifetime extends to the reference's scope, preventing dangling references.
Dynamic Objects (pointers):
Dynamic objects created with new are destroyed with delete. Multiple destructions, accessing a destroyed object, or destroying with incorrect means (e.g., delete[]) result in undefined behavior. Exceptions during dynamic object construction lead to memory release before exception propagation.
Dynamic Arrays:
Dynamic arrays created with new[] are destroyed with delete[]. Multiple destructions, incorrect means of destruction, and access after destruction lead to undefined behavior. Exceptions during array element construction lead to the destruction of previously constructed elements and memory release.
Reference-Counting Smart Pointers:
Dynamic objects managed by std::shared_ptr are destroyed when the last shared_ptr object sharing the object is destructed. Using smart pointers helps prevent memory leaks and ensure proper cleanup.
The above is the detailed content of When and How Are Objects Destroyed in C ?. For more information, please follow other related articles on the PHP Chinese website!