I have a class with a pointer to an integer.
Then a static function that will return the value of that integer.
I'm noticing when calling the static function the destructor is called for that object everytime.
I don't understand why this behavior is happening.
class Dog
{
public:
Dog(int val){
this->pVal = new int(val);
}
~Dog(){
delete this->pVal;
}
static int GetVal(Dog d){
return *(d.pVal);
}
int *pVal;
};
That is the class.
Here is my test driver code.
Dog fido(20);
std::cout << Dog::GetVal(fido); //20 and destructor for fido called
Dog rex(21);
std::cout << Dog::GetVal(fido); //21 but should be 20
std::cout << Dog::GetVal(rex); // should be 21
I'm noticing that both dog objects live at different memory addresses but the int pointer lives at the same address. I believe this is because fido's destructor is called when calling GetVal but I don't know why that behavior is occuring.
Although the destructor for "Fido" is indeed being called, this is not the original "Fido", but its copy. Your GetVal(Dog d) function takes Dog by value, which means that "Fido" is copied before being passed to GetVal, and then the copy is destroyed upon completion.
Passing Dog& by const reference fixes this problem:
static int GetVal(const Dog& d){
return *(d.pVal);
}
Demo.
Note: The above does not explain why you get 21 for "Fido". Since you did not define a copy constructor or an assignment operator, the compiler generated a trivial copy constructor for you. As the result, pVal in "Fido"'s copy is pointing to the same location as pVal in the original "Fido". As soon as the copy gets destroyed upon return from Dog::GetVal(fido) the memory becomes eligible for reuse, and the pointer inside the original "Fido" becomes dangling. When you call Dog::GetVal(fido) for the second time, the function causes undefined behavior by dereferencing a dangling pointer. The fact that the second call prints 21, the value that you passed to "Rex"'s constructor, strongly suggests that the memory freed up on destroying "Fido"'s copy is being reused immediately in constructing "Rex". However, there is no requirement for C++ to do that. If this happens, your code causes UB for the second time when "Rex" and "Fido" are destroyed at the end of the run.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With