ccp*_*lus 2 c++ valgrind memory-leaks object
我的第一个问题是添加地图的对象 A(v),退出范围时应该自动删除吗?
我的第二个问题是,当程序退出时,添加到地图中的对象会发生什么?我相信当我执行 a_[name] = A(v); 时,副本会存储到地图中。另外,我需要提供复制构造函数吗?
void B::AddA(std::string name, int v) {
a_[name] = A(v);
}
Run Code Online (Sandbox Code Playgroud)
我的最后一个问题是,我没有使用“new”创建任何对象,我不需要删除任何对象。
我不明白泄漏从哪里来。
我很感激任何帮助。谢谢。
完整代码
#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);
}
Run Code Online (Sandbox Code Playgroud)
瓦尔格林德
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)
Run Code Online (Sandbox Code Playgroud)
==xxxx== in use at exit: 72 bytes in 1 blocks
==xxxx== still reachable: 72 bytes in 1 blocks
Run Code Online (Sandbox Code Playgroud)
这些仅意味着当程序退出时,仍然存在您仍然有引用的活动内存。内存并没有完全丢失,这就是通常所说的严格意义上的内存泄漏,将列在definitely lost或indirectly lost和 下possibly lost。当程序结束时,是否还有未释放的内存并不重要。
但是,这仍然可能是问题的征兆,例如,如果应该被销毁且具有带副作用的析构函数的对象未运行。
在你的情况下,问题是exit(0)通话。调用std::exit会立即结束程序并进行一些清理。清理包括销毁具有静态存储持续时间的对象,但不包括具有自动存储持续时间的对象,这些对象通常在离开其范围时被销毁。
在您的情况下B b;,包括它存储的所有元素,通常会在}orreturn语句处被销毁main,但因为您exit事先调用,所以它永远不会被销毁。在这种特殊情况下,这不是问题,但如果例如b是一个具有析构函数的对象,该对象应该执行一些在程序外部可见的副作用的操作,则可能是问题。
您不应该调用exit(0)从 退出程序main。只需使用return 0;或完全省略它,因为main具体而言,没有 return 语句相当于return 0;.
旁注:您不应该显式声明/定义不执行任何操作且不执行任何操作的析构函数virtual,例如A::~A() {}. 如果您根本没有在类中声明析构函数,编译器将自动为您生成析构函数,并且行为完全相同。
无论如何,手动声明析构函数都会对特殊成员函数的其他隐式生成产生影响,这可能会影响程序的性能,并且也使得一致遵循0/3/5 规则变得更加困难。
我的第一个问题是添加地图的对象 A(v),退出范围时应该自动删除吗?
A(v)是一个临时对象,将在完整表达式结束时被销毁a_[name] = A(v)。
另外,我需要提供复制构造函数吗?
不,如果您不手动声明一个成员(与析构函数相同),则编译器会隐式声明一个成员,并且假设这是可能的,它将被定义为简单地复制每个成员。无论如何,这通常是您想要的。
我的最后一个问题是,我没有使用“new”创建任何对象,我不需要删除任何对象。
是的,这是完全正确的。