So I'm curious of the reason the following code crashes. Will appreciate help.
#include <iostream>
using namespace std;
class temp
{
public:
temp(int i)
{
intPtr = new int(i);
}
~temp()
{
delete intPtr;
}
private:
int* intPtr;
};
void f (temp fInput)
{
cout << "f called" << endl;
}
int main()
{
temp x = 2;
f(x);
return 0;
}
new
. Or you could just not use new
and have an integer instead of a pointer to an integer - Peter Wood 2012-04-04 21:47
The pointer is copied when x is passed (implicit copy constructor) and the destructor is called twice (before the function returns and before main returns), thus the memory is deleted twice.
Use std::shared_ptr<int>
here instead instead of a raw int pointer (assuming you want the behavior to be the same, i.e. reference the same int
from both temp
s; otherwise, implement the copy constructor, move constructor and assignment operator yourself).
#include <memory>
class temp {
public:
temp(int i) : intPtr(std::make_shared<int>(i)) {
}
private:
std::shared_ptr<int> intPtr; // reference counting ftw
};
sahred_ptr
. Horrible, horrible, lazy design - Ed S. 2012-04-04 21:38
The crash occurs because of the way you are passing x
.
After the scope of the f
function, x
's destructure will be called and will delete intPtr
.
However, that will delete memory that is still in scope for main
. Therefor, after return 0
is called, it will try to delete memory that already exists as you are calling delete twice on the same pointer.
To fix this error, change
void f (temp fInput)
to
void f (const temp& fInput)
Alternatively, you could look into using a std::shared_ptr.
You are violating The Rule of Three
You maintain a pointer member and you pass a copy of the object to the function f
. So, the end result is that you call delete
twice on the same pointer.
The problem you're hitting here is a double delete. Because you didn't define any copy constructors here C++ is happily doing so for you. The implementation does this by performing a shallow copy of all of the contents.
f(x);
This line works by creating a copy of x
and passing it to f
. At this point there are 2 temp
instances which own a single intPtr
member. Both instances will delete that pointer and this is likely what is causing your crash.
To work around this you can take a number of steps
shared_ptr<T>
An example of #2 is
class temp {
temp(const temp& other);
temp& operator=(const temp& other);
public:
// Same
};
Now the f(x)
line simply won't compile because it can't access the necessary copy constructor. It forces it to instead redefine f
to prevent a copy.
void f(const temp& fInput) {
...
}