You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中如何释放传递给成员函数的new对象内存?

Let's break down your problem first: you've built a doubly linked list where each new Link is inserted before the current node, and the Cars pointer ends up pointing to the last inserted node ("Volvo"). Just calling delete Cars will only free that final node—all the earlier nodes ("Hummer", "Ferrari", "Ford") are still in memory with no way to access them, causing a memory leak.

Here are a few solid solutions to fix this:


1. Manually Traverse and Free Each Node

This is the most straightforward approach if you want full control over memory deallocation. You just need to iterate through the entire linked list, save the next node's pointer before deleting the current one, and repeat until you've cleared all nodes.

Add this code at the end of your main function:

// Traverse the list and free every node
Link* current = Cars;
while (current != nullptr) {
    Link* nextNode = current->getSuccessorLink(); // Save the next node first
    delete current;
    current = nextNode;
}

This works because each node's _successor points to the next node in the chain (Volvo → Hummer → Ferrari → Ford → nullptr). By saving nextNode before deleting current, you don't lose access to the rest of the list.


2. Add a Destructor to Automatically Free the Chain

If you want to avoid manual traversal, you can add a destructor to the Link class that recursively frees the successor node. This way, deleting the head node (Cars) will trigger a chain reaction that deletes every node in the list.

Update your Link class with a destructor:

class Link{
public:
    // Your existing constructor
    Link(const std::string& value, Link* previous = nullptr, Link* successor = nullptr) 
        : _value{ value }, _previous{ previous }, _successor{ successor }{}
    
    Link* Insert(Link* new_link);
    
    Link* getPreviousLink() const{ return _previous; }
    Link* getSuccessorLink() const{ return _successor; }
    
    std::string _value;

    // New destructor
    ~Link() {
        delete _successor; // Recursively delete the next node
    }

private:
    Link* _previous;
    Link* _successor;
};

Now, all you need to do at the end of main is:

delete Cars;

When you delete Cars (the "Volvo" node), its destructor deletes "Hummer", which in turn deletes "Ferrari", and so on until "Ford" is deleted (since its _successor is nullptr).

Caveats for This Approach:

  • This only works for non-circular linked lists. If your list ever forms a loop, this will cause infinite recursion and undefined behavior.
  • If any other pointers point to nodes in the list, deleting Cars will invalidate those pointers (they'll become dangling pointers). Use this only if Cars is the sole owner of the entire list.

To avoid manual memory management entirely, switch to using std::unique_ptr (for exclusive ownership) or std::shared_ptr (for shared ownership). Smart pointers automatically free memory when they go out of scope, eliminating leaks.

Here's a quick adaptation of your Link class using std::unique_ptr for the successor node (since each node owns its successor):

#include <memory>
#include <string>

class Link{
public:
    Link(const std::string& value, Link* previous = nullptr, std::unique_ptr<Link> successor = nullptr) 
        : _value{ value }, _previous{ previous }, _successor{ std::move(successor) }{}
    
    std::unique_ptr<Link> Insert(std::unique_ptr<Link> new_link){
        if (!new_link) return std::unique_ptr<Link>{};
        if (!this) return std::move(new_link);

        new_link->_successor.reset(this);
        if (_previous) {
            _previous->_successor = std::move(new_link);
        } else {
            new_link->_previous = _previous;
            _previous = new_link.get();
            return std::move(new_link);
        }
        return std::unique_ptr<Link>{};
    }

    Link* getPreviousLink() const{ return _previous; }
    Link* getSuccessorLink() const{ return _successor.get(); }
    
    std::string _value;

private:
    Link* _previous; // No smart pointer here—we don't own the predecessor
    std::unique_ptr<Link> _successor; // We own the successor
};

With this setup, you can create nodes using std::make_unique, and when the head unique_ptr goes out of scope, it will automatically free the entire list without any manual delete calls.


内容的提问来源于stack exchange,提问作者xIIPANIKIIx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:54:20