The situation is a lot more complicated than you think.
In your first example, the constructor you defined is first called on the line where you create the base object. It allocates an integer (e.g. at 0x00402222) and sets its value.
Then you call fun() and pass the object. Since it's a value parameter, a copy of the object is created, and the copy copy constructor is called for the new object. Since you don't have one defined, this means the default one is used, which just copies the class bit by bit. The new object now contains a pointer which points to the same integer (at 0x00402222) as the object in main().
When fun() returns, the object you passed is destroyed. Its destructor is called and it deletes the integer at 0x00402222. That memory is no longer valid.
Finally, main() returns as well, and the object there is destroyed as well. Its destructor is called. And since its pointer also points to 0x00402222, it attempts to delete memory that has already been deleted, probably leading to a crash in debug mode.