在C-world中度过一段时间后,我回顾了C ++。我有一个基本的问题,我将围绕基于列表的堆栈的实现。
课程' ListStack'有一个节点'结构类型。这是头文件ListStack.h的相关部分:
private:
int count;
struct Node{
Node *next;
void *data;
}
Node *head;
在ListStack.cpp中,这里是构造函数和析构函数。在析构函数中,我释放客户端自己动态分配的数据(假装是这种情况,忽略设计)但不释放任何节点:
ListStack::ListStack(){
head = NULL;
count = 0;
}
ListStack::~ListStack(){
while (head != NULL){
void *data = pop();
free (data);
}
}
这是正确的做法吗?对我来说,朦胧的地方是:
1)通过Node *new = new Node
创建的每个新节点让我觉得我必须通过调用delete来释放节点。但是,正如您所看到的那样,struct Node(在标题中定义)没有析构函数,那么delete会做什么?
2)我觉得解放过程不正确,我应该调用删除数据吗?如果您不知道他们是否使用了malloc或者新的数据,您甚至会如何释放客户端动态分配的数据?
来自C,关于内存的一切是否非常清楚,当手动处理数据(免费或删除)以及C ++负责处理数据时,它会让我感到朦胧。
答案 0 :(得分:1)
1)
但是,正如您所看到的那样,struct Node(在标头中定义)没有 有一个析构函数,那么删除会做什么?
删除将释放已分配的内存。此外,编译器将为Node
创建一个默认析构函数,因为您尚未声明它。调用delete时将调用此默认析构函数。请参阅http://en.cppreference.com/w/cpp/language/destructor(隐式声明的析构函数和隐式定义的析构函数):
如果没有为类类型(struct
,class
或union
)提供用户定义的析构函数,编译器将始终将析构函数声明为内联公共同类的成员。
2)
我应该调用删除数据吗?
您需要删除/释放该实例拥有的所有内存。在你的情况下,我猜你需要迭代列表并删除每个节点。在删除当前节点之前,请确保保留指向下一个节点的指针,否则它将丢失。所以像这样:
ListStack::~ListStack()
{
Node* currentNode = head;
while (currentNode != NULL)
{
Node* nextNode = currentNode->next;
delete currentNode;
currentNode = nextNode;
}
}
这只会删除Node
。如果您动态分配了data
字段,那么您也需要delete currentNode->data
。
如果您将如何释放客户端动态分配的数据? 你不知道他们是使用malloc还是新手?
我不确定你的意思。既然你正在编写类,你就会知道你是使用malloc还是new来分配内存,对吗?