用C ++中的new分配的堆内存的范围

时间:2018-11-15 10:24:12

标签: c++

数据结构新手,最近学习Listnode。有问题。 定义一个ListNode:

struct ListNode
{
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(NULL) {}
};
void AddToTail(ListNode** head, int value)
{
    ListNode* nlist = new ListNode(value);
    if(*head == NULL)
    {
        *head = nlist;
    }
    else
    {
        ListNode* p = *head;
        while(p->next != NULL)
        {
            p = p->next;
        }
        p->next = nlist;
    }
    // No need to delete nlist, since the memory allocated by it is already organized by the ListNode.
}

int main()
{
    ListNode* L = new ListNode(5);
    AddToTail(&L, 10);
    ListNode* p = L;
    while(p->next != NULL)
    {
        p = p->next;
    }
    printf("Final value is %d.\n", p->val);
    delete L;
}

到现在为止,一切似乎还好吧?我想知道如果不在堆中分配ListNode内存,那意味着我不使用new,而我使用ListNode L;然后手动对其进行初始化。它的内存现在已堆叠。添加到它的尾部在堆内存中。我现在如何删除堆内存。看来ListNode内存的一部分在堆栈中,而一部分在堆中?我正确理解了吗?

2 个答案:

答案 0 :(得分:4)

是的,L是否动态分配并不重要。那就这样。实际上,这里没有理由动态分配它。

重要的是它管理的节点的所有权和生存期。这些是动态分配的,因此您需要在ListNode内部使用一个析构函数,以取消链接并取消分配节点。

“混合”存储期限没有什么问题-例如,这就是您每次实例化std::vector<int>时所做的事情。您只需要确保所有拥有动态分配的数据都具有清除自身的功能。

答案 1 :(得分:1)

您需要像这样的删除功能

    void DeleteList(ListNode** head)
    {
        ListNode* p = *head;
        while(p != NULL)
        {
            ListNode *t = p->next;
            delete p;
            p = t;
        }
    }

    // and call it in main:

    printf("Final value is %d.\n", p->val);
    DeleteList(&L);

但是最好立即在一个特殊的类中定义所有这些操作,例如List:

class List
{
private:
    ListNode  *head;
public:   
    List() : head(NULL){}
    ~List() { Clear(); }
    void AddToTail(int value);
    void Clear();      
};

void List::AddToTail(int value)
{
    ListNode* nlist = new ListNode(value);
    if(head == NULL)
    {
        head = nlist;
    }
    else
    {
        ListNode* p = head;
        while(p->next != NULL)
        {
            p = p->next;
        }
        p->next = nlist;
    }
}


void List::Clear()
{
    ListNode* p = head;
    while(p != NULL)
    {
        ListNode *t = p->next;
        delete p;
        p = t;
    }
    head = NULL;
}

并像这样使用它:

List lst;
lst.AddToTail(5);
lst.AddToTail(10);
lst.AddToTail(20);
lst.AddToTail(30);
lst.Clear();