如何删除在函数参数上声明的新指针
How to delete new pointer that declared on function parameters?
我的类有一个成员函数,它将自己类型的指针作为参数。
当我这样做时:
Object* obj1 = new Object();
Object* obj2 = new Object();
obj1->add_child(obj2)
delete obj1;
delete obj2;
obj1 = NULL;
obj2 = NULL;
并运行valgrind
,报告称:
HEAP SUMMARY:
in use at exit: 72,704 bytes in 1 blocks
total heap usage: 6 allocs, 5 frees, 73,098 bytes allocated
LEAK SUMMARY:
definitely lost: 0 bytes in 0 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 72,704 bytes in 1 blocks
suppressed: 0 bytes in 0 blocks
我看到一个答案说still reachable
很好,没有泄漏。然后,当我尝试这个:
Object* obj = new Object();
obj1->add_child(new Object());
delete obj;
obj = NULL;
valgrind
的报告说:
HEAP SUMMARY:
in use at exit: 72,877 bytes in 3 blocks
total heap usage: 6 allocs, 3 frees, 73,098 bytes allocated
LEAK SUMMARY:
definitely lost: 144 bytes in 1 blocks
indirectly lost: 29 bytes in 1 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 72,704 bytes in 1 blocks
suppressed: 0 bytes in 0 blocks
很明显,我没有删除作为参数传递的new Object()
指针。那么,我该如何删除那个指针呢?
详细更新
add_child(Object* obj)
:的定义
void add_child(Object* obj) {
container.add_child(obj);
}
container
是作为模板类实例的Object
的成员。
Container<Object> container;
Container
的定义是:
template<class T>
class Container {
public:
void add_child(const std::string& key, T* child) {
childrens.insert(std::pair<std::string,T*>(key, child));
}
private:
std::multimap<std::string,T*> childrens;
}
那么,孩子们实际上就是一个std::multimap
。
我希望这个问题不要太久。
您需要对拥有指针的人做出明确而一致的选择。如果您决定add_child
拥有所有权,则调用方应认为他们不需要删除传入的指针。如果您决定add_child
不拥有所有权,则调用方保留所有权并删除指针。
你可以让Object
拥有所有权,这样它的析构函数就会删除所有添加到它的子指针
Object* obj1 = new Object();
Object* obj2 = new Object();
obj1->add_child(obj2);
delete obj1; // also deletes obj2 automatically
第二个:
Object* obj = new Object();
obj->add_child(new Object());
delete obj; // automatically deletes the unnamed pointer passed in on previous line
如果您不希望Object
拥有所有权,那么您就有问题了,因为您无法在调用者的上下文中删除new Object()
。
如果你使用智能指针,管理所有权就会变得容易得多。add_child
可以采用std::unique_ptr<Object>
参数。
auto obj1 = std::make_unique<Object>();
auto obj2 = std::make_unique<Object>();
obj1->add_child(std::move(obj2)); // obj1 takes ownership
// both pointers automatically deleted at scope exit
auto obj = std::make_unique<Object>();
obj->add_child(std::make_unique<Object>());
// both pointers automatically deleted at scope exit
一旦函数调用完成,就不再有new
创建的指针。如果您调用的函数没有删除指针,则表示内存泄漏。
关于仍然可以访问的内存块的valgrind报告不是你的错,而是gcc 5.1中的错误。
我是怎么想到这个的:
块大小非常大(72704
(,与分配的对象的大小不匹配,所以接下来我尝试将72704
除以144
和29
,看看它是否是这些对象的数组。
但事实并非如此,因为72704
、72704-4
和72704-8
(数组,数组+32位整数存储大小,数组+64位整数存储尺寸(都不可分割。然后我在谷歌上搜索了"72,704 still reachable
",显示了上面提到的问题。
其他回答者建议使用智能指针(如std::unique_ptr
和std::shared_ptr
(是合理的,我也建议使用它们。
- 为什么我必须以这种方式声明指针?
- 声明指针时更改星号的位置
- 为什么要在初始化SDL之前在SDL中声明指针
- 在C++中声明指针的 2D 数组的方法
- 如何在C 中使用不同数据类型的类模板指针声明指针
- 如何声明指针/引用对模板类成员类型
- C :如何使用thread_local声明指针变量
- 声明指针时的隐式内存分配和初始化
- 了解初始化和声明指针变量时的警告和编译错误
- 在标头中声明指针会导致访问冲突
- 为什么我不能转发声明指针结构?
- 声明指针的动态数组
- 正在声明指针的类型
- C++11 decltype:如何声明指针指向的类型
- C++ 转发声明(指针) - 访问成员
- 为什么我可以在头文件中声明数组,但不能声明指针
- 为什么我需要声明指针而不是对象
- 我们可以声明指针的大小吗?
- 错误 C2143:语法错误:声明指针时'*'之前缺少';'
- 在实现类之前声明指针时出现问题