void add_first(int e) {
Node* newest = new Node(e, first);
first = newest;
n++;
}
在这段代码中,我宣布了一个节点指针"最新的"。
list->add_first(4);
让我说我第二次称这个功能。
list->add_first(8)
从我第一次调用指向新节点的函数开始是否仍然是相同的*最新版本或在函数之后执行前一个*最新的模具并且在第二个函数调用时生成了新的*最新版本?
//完整代码以防您需要额外信息
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);
}
};
答案 0 :(得分:2)
指针只是包含特定类型实例的内存地址的类型。在您的示例中,您使用Node
动态分配内存以存储new
的实例,并将其地址存储到指针(注意new
返回指向已分配内存的指针) 。当函数返回时,指针&#34;死掉&#34;,但分配的内存仍然被分配。
答案 1 :(得分:2)
new Node(e, first)
将在堆上为类型为Node
的对象分配新内存,在此对象将保留,直到您使用delete
手动释放它。如果你没有保留对它的引用,那么你就不能解除它并且你有内存泄漏。
Node* newest = ...;
将在堆栈上创建类型为Node
的指针,直到它超出范围(在这种情况下,当函数返回时),初始化它以引用刚刚创建的对象。
重要的是要注意newest
不是对象;它只是暂时引用它。
first = newest;
此处未提供first
的类型,但可能为了编译它,在更高的范围内定义,例如一个成员变量,并接受类型为Node*
的赋值...所以它本身可能是Node*
。
在这种情况下,默认情况下会将first
设置为引用newest
指向的同一对象。在这种情况下,不指向newest
,但两者现在都引用了同一个对象。
当函数返回时,newest
(指针)将被销毁,因为它是在函数调用的范围内定义的,但是你创建的Node
对象也将存在于堆中, as first
引用它,因为它在此范围之外定义。
如果您再次立即调用此功能,例如在循环中,您将分配另一个类型为Node
的对象,将first
设置为该对象,而first
先前指向的对象现在在堆上孤立而没有引用。< / p>
编辑:我刚刚注意到您已将first
传递给Node
的构造函数,因此您可能会在其中进行单独的连接。
答案 2 :(得分:1)
newest
(即指针)会死(因为它是局部变量)。下次调用该函数时,会再次创建并销毁新的newest
变量。
*newest
(即它指向的对象)保持活着状态,直到您明确delete
它为止(因为您使用new
创建了它)