[英]memory leak and I don't know why
我的第一个问题是添加map的object A(v),退出scope时应该自动删除吗?
我的第二个问题是,当程序退出时,添加到 map 中的 object 会发生什么情况? 我相信当我执行 a_[name] = A(v); 时,一份副本会存储到 map。 另外,我需要提供一个复制构造函数吗?
void B::AddA(std::string name, int v) {
a_[name] = A(v);
}
我的最后一个问题是我没有使用“新”创建任何 object,我不需要删除任何内容。
我不明白泄漏是从哪里来的。
我很感激任何帮助。 谢谢你。
完整代码
#include <map>
#include <string>
#include <iostream>
class A {
public:
int vala_;
A();
~A();
A(int v);
};
A::A() {
vala_ = 0;
}
A::~A() {}
A::A(int v) {
vala_ = v;
}
class B {
public:
int valb_;
std::map<std::string, A> a_;
B();
~B();
void AddA(std::string name, int v);
};
B::B() {
valb_ = 0;
}
B::~B() {
}
void B::AddA(std::string name, int v) {
a_[name] = A(v);
}
int main() {
B b;
b.AddA("wewe", 5);
std::cout << b.a_["wewe"].vala_ << std::endl;
exit(0);
}
瓦尔格林
I replaced the number ==????==, to ==xxxx==. I guess it was the process id.
==xxxx== Memcheck, a memory error detector
==xxxx== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==xxxx== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==xxxx== Command: ./a.out --leak-check=full -s
==xxxx==
5
==xxxx==
==xxxx== HEAP SUMMARY:
==xxxx== in use at exit: 72 bytes in 1 blocks
==xxxx== total heap usage: 3 allocs, 2 frees, 73,800 bytes allocated
==xxxx==
==xxxx== LEAK SUMMARY:
==xxxx== definitely lost: 0 bytes in 0 blocks
==xxxx== indirectly lost: 0 bytes in 0 blocks
==xxxx== possibly lost: 0 bytes in 0 blocks
==xxxx== still reachable: 72 bytes in 1 blocks
==xxxx== suppressed: 0 bytes in 0 blocks
==xxxx== Rerun with --leak-check=full to see details of leaked memory
==xxxx==
==xxxx== For lists of detected and suppressed errors, rerun with: -s
==xxxx== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==xxxx== in use at exit: 72 bytes in 1 blocks
==xxxx== still reachable: 72 bytes in 1 blocks
这些仅意味着当程序退出时,您仍然有引用的 memory 仍然存在。 memory 并没有完全丢失,这就是通常所说的严格意义上的 memory 泄漏,将列在definitely lost
或indirectly lost
和possibly lost
下。 当程序结束时,是否还有未释放的 memory 并不重要。
但是,这仍然可能是问题的征兆,例如,如果应该销毁且具有带副作用的析构函数的对象未运行。
在您的情况下,问题是exit(0)
调用。 调用std::exit
会在此处结束程序并进行一些清理。 清理包括销毁具有 static 存储期限的对象,但不包括具有自动存储期限的对象,这些对象通常会在其 scope 离开时被销毁。
在你的情况下B b;
,包括它存储的所有元素,通常会在main
的}
或return
语句中被销毁,但是因为您事先调用了exit
,所以它永远不会被销毁。 在这种特殊情况下,这不是问题,但如果例如b
是一个 object ,它应该执行一些在程序外部可见副作用的操作的析构函数,它可能是。
您不应该调用exit(0)
从main
退出程序。 只需使用return 0;
或者完全忽略它,因为对于main
来说,没有 return 语句等同于return 0;
.
旁注:您不应显式声明/定义不做任何事情且不是virtual
的析构函数,例如A::~A() {}
。 如果您根本没有在 class 中声明析构函数,编译器将自动为您生成它并且行为完全相同。
无论如何手动声明析构函数会对特殊成员函数的其他隐式生成产生影响,这可能会影响程序的性能,并且也使得始终遵循0/3/5 规则变得更加困难。
我的第一个问题是添加map的object A(v),退出scope时应该自动删除吗?
A(v)
是一个临时的 object 并将在完整表达式a_[name] = A(v)
的末尾被销毁。
另外,我需要提供一个复制构造函数吗?
不,如果您不手动声明一个(与析构函数相同),编译器会隐式声明一个,并且假设这是可能的,它将被定义为简单地复制每个成员。 无论如何,这通常是您想要的。
我的最后一个问题是我没有使用“新”创建任何 object,我不需要删除任何内容。
是的,这完全正确。
“仍然可达”并不严格意味着它是memory 泄漏。 我相信这是因为你调用了exit(0)
而不是仅仅返回 0。堆栈没有被清理,因为程序被信号终止了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.