通过函数内部的指针删除

时间:2015-01-14 06:03:25

标签: c++ pointers

考虑

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

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

说我们有:

int *y = new int{22};
d(y);
d2(y);
  • 在第一种情况下(d(y)),我的理解是创建指针的副本。
  • 在第二种情况下,我的理解是我通过引用传递它,所以仍然有一个指针指向y

在这两种情况下,我都预料到:

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

导致未定义的行为,因为我应该删除t的值。但我仍然可以成功取消引用它,好像&#34;删除t;&#34;什么也没做。那是为什么?

1 个答案:

答案 0 :(得分:3)

  

&#34;导致UB&#34; /&#34;但我仍然可以成功地取消引用它,好像&#34;删除t;&#34;什么也没做。为什么?&#34;

&#34;成功&#34;因为它可以编译,但不能成功地#34;如同在&#34;不必担心UB&#34;。为什么?因为编译器在编译期间没有尝试(或期望)建模运行时程序状态:确保程序在运行时不会尝试使用未定义的行为,这是你的工作。

  

在第二种情况下,我的理解是我通过引用传递它,所以仍然有一个指针指向y

不...你没有指向y的任何信息......你引用了y。无论如何,int之后的delete t不存在,反之亦然:当你复制指针时 - 调用d()而不是d2() },调用者的y副本不受影响,并成为指向int曾经存在的位置(完全没用)的悬空指针。此外,如果调用d(y);,则d2(y);delete t;语句中的行为未定义,而不仅仅是*t