C++ 为什么引用可以保存指针指向的对象,即使该指针已被删除?

C++ 为什么引用可以保存指针指向的对象,即使该指针已被删除?,c++,pointers,reference,C++,Pointers,Reference,当我在二项式堆中学习数据结构时,我阅读了Weiss的代码实现。一些代码如下: 节点实现和deleteMin算法如下: template<typename Comparable> struct BinomialNode { Comparable element; BinomialNode *leftChild; BinomialNode *nextSibling; }; void deleteMin( Comparable & minItem

当我在二项式堆中学习数据结构时,我阅读了Weiss的代码实现。一些代码如下:

节点实现和deleteMin算法如下:

template<typename Comparable>

struct BinomialNode
{
    Comparable    element;
    BinomialNode *leftChild;
    BinomialNode *nextSibling;
};

void deleteMin( Comparable & minItem )
{   
    int minIndex = findMinIndex( );
    minItem = theTrees[ minIndex ]->element;
    BinomialNode *oldRoot = theTrees[ minIndex ];
    BinomialNode *deletedTree = oldRoot->leftChild;
    delete oldRoot;
}
模板
结构二进制节点
{
可比元素;
BinomialNode*leftChild;
BinomialNode*下一个绑定;
};
无效删除最小值(可比和最小值)
{   
int minIndex=findMinIndex();
minItem=树[minIndex]->元素;
BinomialNode*oldRoot=树[minIndex];
BinomialNode*deletedTree=oldRoot->leftChild;
删除oldRoot;
}
但我被“可比和最小项”弄糊涂了。如我们所见,“minItem”保存元素。但是很快“oldRoot”就被删除了!“element”成员位于“oldRoot”的内部!有人能告诉我地位的原则吗

我还做了一些其他的测试

struct Node{
    int i;
    Node * next;
    Node(int i, Node* next = nullptr): i(i), next(next){}
};

void getInt(int & i){
    int * p = new int(3);
    i = *p;
    delete p;   //the reference can get the true value??? =>output: 3(right)
}

void getInt(int * &i){
    int * p = new int(3);
    i = p;
    delete p;   //pointer can't get the real number because of deletion => output: 6904432(wrong)
}

int main()  //for test
{
    Node* child = new Node(3);
    Node* root = new Node(1, child);
    int i;

    getInt(i);
    cout << i << endl;

    int * m; 
    getInt(m);
    cout << *m;
}
struct节点{
int i;
节点*下一步;
Node(inti,Node*next=nullptr):i(i),next(next){
};
void getInt(int&i){
int*p=新的int(3);
i=*p;
删除p;//引用可以得到真实值???=>输出:3(右)
}
void getInt(int*&i){
int*p=新的int(3);
i=p;
delete p;//指针无法获取实数,因为deletation=>output:6904432(错误)
}
int main()//用于测试
{
节点*子节点=新节点(3);
节点*根=新节点(1,子节点);
int i;
getInt(i);

cout若你们问二项式代码是否有问题,那个么答案是否定的,分配参数并没有什么问题

在第一个代码中,
minItem=theTrees[minIndex]->元素;
将对象复制到作为引用传递的对象,因此之后没有对删除的任何对象的引用(假设Comparable不知道BinomialNode).参数的引用是指传递的对象,而不是指数据结构中的任何内容

测试也是如此:在
getInt(i)
之后,int只包含3

但是,
void getInt(int*&i)
返回一个悬空指针,因此这是一个糟糕的代码


编辑不完整:答案是用参考参数解决假设问题,但二项式代码
void deleteMin(Comparable&minItem)
包含2个问题,希望在本书后面部分解决:

  • 没有处理
    findMinIndex()
    失败的情况。空堆会发生什么情况

  • BinomialNode*deletedTree=oldRoot->leftChild;
    :对deletedTree不做任何操作,这至少会导致内存泄漏并实际丢失信息


  • 基本上,在代码> >删除>代码>之后,你不允许访问<代码> int >代码。碰巧你的系统还没有清除那个内存,但是,就你而言,它已经消失了。你不允许看和看。这被调用。C++使某些事情违法,而不必强迫每次检查它。基本上,如果这会降低你的速度,语言就不会控制住你的手。嗯……我想问的另一件事是引用是否安全?不确定你的确切意思,但如果你有一个引用已经被
    delete
    d,那就是UB。几乎与悬空指针完全相同。这对我来说非常重要不要犯下未定义的行为。你的程序很容易看起来工作正常,但实际上却坏了。你可能会得到微妙的错误结果,或者崩溃,或者只有当你移动到另一台计算机时它才会坏掉,或者各种各样的有问题的结果。最糟糕的是,它看起来工作正常,并且只在一台计算机上坏掉几年前。我投票结束这个问题,因为询问未定义行为的行为是徒劳的。首先谢谢你的回答!但是为什么要“复制”?正如我所知,引用就像一个别名,就像“对象本身”。因此,我认为它已被删除…分配给引用并不会更改它引用的对象。它会更改被引用对象的值。通常,这意味着
    a=b
    会将
    b
    的副本存储到
    a
    引用的对象中。wind2412:我认为你的评论表明了问题中的混乱。I希望我的回答和@Peter的评论能解决这个问题。感谢你的解释!我完全理解所有细节。不客气。请注意,你的问题标题有误导性,因为这似乎是UB的一部分,我们大多数人都挑了它。