Reputation: 187
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
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 Word
s 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
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