Stephen Wong
Stephen Wong

Reputation: 187

C++ destructor called before lifetime of scope

I have a question about triggering a destructor for an object prematurely. I have an dynamically allocated array of pointers to dynamically allocated Word objects. The name of the array is words_. words_ is a class attribute of another class called Dictionary.

In my Dictionary class, I have a function where I access each Word object and call a member function of the Word class.

The below code triggers the destructor prematurely:

Word *curr_word_ptr = words_[idx]; // This line is okay, doesn't trigger destructor
Word curr_word = *curr_word_ptr; // This line triggers the destructor prematurely
curr_word.callMemberFunc();

Because of the second line, as soon as the scope of the function ends, the destructor is called.

But if I access it through the array indices alone:

*(words_[idx]).callMemberFunc(); // The desctructor is not called prematurely

Is the problem because I have a stack variable (not even a stack pointer variable) accessing a dynamically allocated object? Thus, when the scope of the function ends, both the stack variable (curr_word) and the dynamically allocated stack object gets destroyed?

Thank you.

Upvotes: 1

Views: 257

Answers (2)

kabanus
kabanus

Reputation: 25895

Word curr_word = *curr_word_ptr; defines a local Word, that only lives in the local scope, your function. When the function exits, it is destroyed. Note it is a copy of the initial Word that is destroyed, not the original.

If you want handy syntax so you don't have to dereference all over, or make a copy, use a reference:

Word &word = *curr_word_ptr;

This is the syntactic sugar C++ provides to refer to an object without pointers (directly). Note though, any changes made to word will affect your original word as well in this case.

The problem is even worse if your Words contains dynamically allocated memory. Assuming you use the default copy constructor, the addresses will be copied. As such, destruction of a local Word will free memory still referenced by the original Word, causing a crash when next accessed.

Upvotes: 6

Marek R
Marek R

Reputation: 37697

Word curr_word = *curr_word_ptr;

creates on stack copy of the object and that copy gets destroyed.

Most probably you class has missing a logic and you need define copy constructor to prevent crashes or disable copy constructor so you can create copy by mistake like here.

*(words_[idx]).callMemberFunc();

Invokes method directly on object pointed by object stored in array. Copy is not created.

Other way you can write this line:

words_[idx]->callMemberFunc();

I see also a problem since you are using raw pointers. Since c++11 this approach is considered bad practice. Learn to use std::uniqie_ptr and std::shared_ptr.

Also use std::vector instead regular C-array

Upvotes: 1

Related Questions