0

Consider

void d(int* t) { //pointer passed by value
    delete t;
    std::cout << *t << '\n';
}

and

void d2(int*& t) { //pointer passed by reference
    delete t;
    std::cout << *t << '\n';
}

Say we have:

int *y = new int{22};
d(y);
d2(y);
  • In the first case (d(y)), my understanding is a copy of a pointer is created.
  • In the second case, my understanding is I passed it by reference, so still one pointer points to y

In both cases, I expected:

std::cout << *t << '\n';

to cause undefined behavior because I should have deleted the value of t. But I can still dereference it successfully, as if "delete t;" did nothing. Why is that?

lightning_missile
  • 2,821
  • 5
  • 30
  • 58

1 Answers1

3

"cause UB" / "But I can still dereference it successfully, as if "delete t;" did nothing. Why is that?"

"successfully" as in it may compile, but not "succesfully" as in "don't have to worry about the UB". Why? Because the compiler's not attempting (or expected) to model your runtime program state during compilation: it's your job to make sure your program won't attempt something with undefined behaviour at runtime.

In the second case, my understanding is I passed it by reference, so still one pointer points to y

No... you don't have any pointers to y... you have a reference to y. Anyway, the ints don't exist after delete t, and it's the other way around: when you copy the pointer - calling d() not d2(), the caller's copy of y is unaffected and becomes a dangling pointer to where the ints used to be (which is totally useless). Further, if d(y); is called then d2(y); has undefined behaviour at the delete t; statement, not just *t.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252