首页 文章

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

提问于
浏览
-2

在C-world工作一段时间后,我回顾了C . 我有一个基本的问题,我将围绕基于列表的堆栈的实现 .

类'ListStack'具有'Node'结构类型 . 这是头文件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(在头文件中定义)没有析构函数,那么删除会做什么?

2)我觉得解放过程不正确,我应该调用删除数据吗?如果您不知道客户端是使用malloc还是new,那么您甚至可以释放客户端动态分配的数据?

来自C,关于内存的所有内容是否都非常清楚,当我必须手动处理(免费或删除)数据以及C处理数据时,我会感到朦胧 .

1 回答

  • 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还是new,那么您甚至可以释放客户端动态分配的数据?

    我不确定你的意思 . 既然你正在编写类,你就会知道你是使用malloc还是new来分配内存,对吗?

相关问题