如何通过' new / delete'处理内存? C ++中的构造函数和析构函数?

时间:2016-01-09 03:01:04

标签: c++ memory-management

在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 ++负责处理数据时,它会让我感到朦胧。

1 个答案:

答案 0 :(得分:1)

1)

  

但是,正如您所看到的那样,struct Node(在标头中定义)没有   有一个析构函数,那么删除会做什么?

删除将释放已分配的内存。此外,编译器将为Node创建一个默认析构函数,因为您尚未声明它。调用delete时将调用此默认析构函数。请参阅http://en.cppreference.com/w/cpp/language/destructor隐式声明的析构函数隐式定义的析构函数):

如果没有为类类型(structclassunion)提供用户定义的析构函数,编译器将始终将析构函数声明为内联公共同类的成员。

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来分配内存,对吗?