C++ 指针是否在函数结束后死亡?

C++ 指针是否在函数结束后死亡?,c++,pointers,C++,Pointers,在这段代码中,我声明了一个节点指针“最新” 假设我第二次调用该函数 list->add_first(4); 还是我第一次调用指向新节点的函数时的*newest,还是前一个*newest在函数之后消失,第二个函数调用时生成了一个新的*newest //完整的代码,以备需要额外信息时使用 list->add_first(8) 模板 班级名单{ 结构节点{ 元素; 节点*下一步; Node(elem=0,Node*next=nullptr):elem(elem),next(next){

在这段代码中,我声明了一个节点指针“最新”

假设我第二次调用该函数

list->add_first(4);
还是我第一次调用指向新节点的函数时的*newest,还是前一个*newest在函数之后消失,第二个函数调用时生成了一个新的*newest

//完整的代码,以备需要额外信息时使用

list->add_first(8)
模板
班级名单{
结构节点{
元素;
节点*下一步;
Node(elem=0,Node*next=nullptr):elem(elem),next(next){
};
节点*第一;
尺寸;
公众:
List():n(0),first(nullptr){}
~List(){
while(第一个!=nullptr){
节点*aux=第一;
第一个=第一个->下一个;
删除aux;
}
}
布尔地址优先(T e){
节点*最新=新节点(e,第一);
第一个=最新的;
n++;
返回true;
}
bool添加(T e,大小\u T p){
如果(p>n)返回false;
如果(p==0)返回addFirst(e);
节点*最新=新节点(e);
节点*aux=第一;
尺寸i=1;
while(i++next;
}
最新->下一步=辅助->下一步;
aux->next=最新;
n++;
返回true;
}
布尔加法(T e){
返回add(e,n);
}
};
最新的
(即指针)在函数返回时消失(因为它是一个局部变量)。下次调用函数时,将创建一个新的
newest
变量并再次销毁


*最新的
(即它所指向的对象)将保持活动状态,直到您显式地
删除它(因为您使用
新建
创建它)

指针只是保存特定类型实例的内存地址的类型。在您的示例中,您使用
new
动态分配内存来存储
节点的一个实例,并将其地址存储到一个指针(注意
new
返回的指针指向分配的内存)。当函数返回时,指针“死亡”,但分配的内存保持分配状态

template <typename T>
class List {
    struct Node {
        T elem;
        Node* next;

        Node(T elem = 0, Node* next = nullptr) : elem(elem), next(next) {}
    };

    Node* first;
    size_t n;

public:
    List () : n(0), first(nullptr) {}
    ~List () {
        while (first != nullptr) {
            Node* aux = first;
            first = first->next;
            delete aux;
        }
    }

    bool addFirst(T e) {
        Node* newest = new Node(e, first);
        first = newest;
        n++;
        return true;
    }
    bool add(T e, size_t p) {
        if (p > n) return false;
        if (p == 0) return addFirst(e);

        Node* newest = new Node(e);

        Node* aux = first;
        size_t i = 1;
        while (i++ < p) {
            aux = aux->next;
        }
        newest->next = aux->next;
        aux->next = newest;
        n++;
        return true;
    }
    bool addLast(T e) {
        return add(e, n);
    }
};
将在堆上为
节点
类型的对象分配新内存,在您使用
删除
手动取消分配之前,该内存将一直保留。如果不保留对它的引用,则无法取消分配它,并且内存泄漏

new Node(e, first)
将在堆栈上创建一个
Node
类型的指针,直到它超出范围(在本例中,当函数返回时),初始化它以引用刚刚创建的对象

需要注意的是,
最新的
不是对象;它只是暂时引用它

Node* newest = ...;
此处未提供
first
的类型,但可能是为了便于编译,它在更高的范围内定义,例如成员变量,并接受
Node*
类型的赋值……因此它可能是
Node*
本身

在这种情况下,默认情况下,这将首先设置
以引用
最新的
指向的同一对象。在这个场景中,它没有指向最新的,但现在两者都引用了相同的对象

当函数返回时,
最新的
(指针)将被销毁,因为它是在函数调用的范围内定义的,但是您创建的
节点
对象将位于堆上,以及引用它的
第一个
,因为它是在此范围外定义的

如果您立即再次调用此函数,例如在循环中,您将分配另一个
节点
类型的对象,将
第一个
设置到该对象,并且先前由
第一个
指向的对象现在在堆上孤立,没有引用


编辑:我刚刚注意到您首先将
传递到
节点的构造函数中,因此您可能在其中建立了一个单独的连接。

在您的示例中,指针确实失效,但是它们存储的内存地址仍然是分配的。你可能应该拿起——所有的事情都会在这里解释,所以我第二次调用这个函数时,它实际上是一个新的*最新的?如果:“*第一个”指向“*最新”和“*最新”指向一个节点,则确定。函数结束后,“*latest”被删除,“*first”仍然指向节点?正确,除非
first
从未指向
latest
。您正在对另一个指针执行
first
赋值,默认情况下,该指针将
first
的地址引用设置为与
最新的
的地址引用相同;实际上,您是在告诉
first
指向
newst
指向的同一对象。实际上,您可以通过执行以下操作将
最新的
完全删除,结果相同:
first=newnode(e,first)
Node* newest = ...;
first = newest;