是valgrind疯了还是这是一个真正的std map迭代器内存泄漏?

Alb*_*lia 5 c++ memory valgrind memory-leaks map

嗯,我对Valgrind和内存泄漏分析器一般都很新.我必须说当你开始使用它们时有点可怕因为你不能不知道你之前可能还有多少泄漏!

到目前为止,由于我不是c ++程序员的经验,我想检查一下这肯定是内存泄漏还是Valgrind做了误报?

typedef std::vector<int> Vector;
typedef std::vector<Vector> VectorVector;
typedef std::map<std::string, Vector*> MapVector;
typedef std::pair<std::string, Vector*> PairVector;
typedef std::map<std::string, Vector*>::iterator IteratorVector;

VectorVector vv;
MapVector m1;
MapVector m2;

vv.push_back(Vector());
m1.insert(PairVector("one", &vv.back()));

vv.push_back(Vector());
m2.insert(PairVector("two", &vv.back()));

IteratorVector i = m1.find("one");
i->second->push_back(10);
m2.insert(PairVector("one", i->second));

m2.clear();
m1.clear();
vv.clear();
Run Code Online (Sandbox Code Playgroud)

这是为什么?clear命令不应该调用每个对象和每个向量的析构函数吗?

在做了一些测试之后,我发现了泄漏的不同解决方案:

1)删除:

i->second->push_back(10);
Run Code Online (Sandbox Code Playgroud)

2)添加:

delete i->second;
Run Code Online (Sandbox Code Playgroud)

3)删除第二个

vv.push_back(Vector());
m2.insert(PairVector("two", &vv.back()));
Run Code Online (Sandbox Code Playgroud)

使用解决方案2)使Valgring打印:10个分配,11个自由可以吗?

因为我没有使用新的为什么要删除?

谢谢你的帮助!

jpa*_*cek 1

您在这里有未定义的行为:

m1.insert(PairVector("one", &vv.back()));

vv.push_back(Vector());
Run Code Online (Sandbox Code Playgroud)

插入会使指向向量的迭代器和引用无效,这也意味着您存储在映射中的指针基本上指向插入后的某个黑洞。

让 Valgring 打印: 10 次分配,11 次释放 可以吗?

奇怪了,它不是也打印一些关于双重​​释放的东西吗?

对于解决方案,我建议使用不同的容器vector(例如list,或deque,其变异函数使迭代器无效,但引用无效)。或者您可以在向量中存储指向数据的指针(最好是智能的,但也可以是普通的),以便实际数据的地址是稳定的。

  • 在您引用的行中,这还不是未定义的行为。存在一个无效的指针是完全合法的,*只要你不取消引用它*。它仅在“i-&gt;second-&gt;push_back(10)”行上变得未定义,其中向量指针实际上被取消引用。 (2认同)