[Solved] Getting undefined behavior for something that shouldn’t be getting undefined behavior


Your code does have undefined behaviour. But let’s start at the beginning.

Sample s1 = new Sample(10);

This is what happens in this line:

  1. A Sample object is allocated on the heap and the new expression returns a pointer to it, a Sample*.
  2. You cannot assign a Sample* to a variable of type Sample. But Sample has a constructor that allows implicit construction from an int. If you use the -fpermissive compiler option (hint: don’t!), the compiler allows implicit conversion of a pointer to an integer – after all, a pointer is just a memory address, a.k.a. a number.
  3. Accordingly s1 is constructed by interpreting the memory address of the heap Sample object as an integer (truncating it if sizeof(Sample*) > sizeof(int)). That’s the value that ends up as *(s1.ptr).

To reiterate the key point: In that line you don’t instantiate one Sample object, but two. Bug 1: The one created on the heap is never deleted. That’s a memory leak.

SomeFunc(s1);

Sample has nothing in it that prevents the compiler from generating the default copy constructor and default copy assignment operator. Important: “default” for pointers means to copy the pointer, not the object behind it. So:

  1. s1 is copied to call SomeFunc(). The copy is available as x in the function. Because of the default pointer copy both s1 and x point to the same int object.
  2. x goes out of scope at the end of the function, the destructor runs and deletes the int object.

We are not quite undefined yet, but we’re getting close.

s1.PrintVal();

The function tries to acces the int object behind the pointer, but it’s already deleted. s1.ptr is a dangling pointer. Bug 2: Dereferencing a dangling pointer is undefined behaviour.

And all that because of that seemingly innocent implicit pointer-to-int conversion … That’s why it is a compiler error by default, at least in non-ancient compilers.

solved Getting undefined behavior for something that shouldn’t be getting undefined behavior