gpt4 book ai didi

c++ - 内存泄漏,我不知道为什么

转载 作者:行者123 更新时间:2023-12-02 18:22:59 24 4
gpt4 key购买 nike

我的第一个问题是添加 map 的对象 A(v),退出范围时应该自动删除吗?

我的第二个问题是,当程序退出时,添加到 map 中的对象会发生什么?我相信当我执行 a_[name] = A(v); 时,拷贝会存储到 map 中。另外,我需要提供复制构造函数吗?

void B::AddA(std::string name, int v) {
a_[name] = A(v);
}

我的最后一个问题是,我没有使用“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);
}

瓦尔格林德

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

这些仅意味着当程序退出时,仍然存在您仍然有引用的事件内存。内存并没有完全丢失,这就是通常所说的严格意义上的内存泄漏,将列在 definitely lost 下。或indirectly lostpossibly lost 。当程序结束时,是否还有未释放的内存并不重要。

但是,这仍然可能是问题的征兆,例如,如果应该销毁且具有带副作用的析构函数的对象未运行。

就您而言,问题是 exit(0)称呼。调用std::exit程序就在那里结束并进行一些清理。清理包括销毁具有静态存储持续时间的对象,但不包括具有自动存储持续时间的对象,这些对象通常在离开其作用域时会被销毁。

就您而言B b; ,包括它存储的所有元素,通常会在}处被销毁或return main的声明,但是因为你打电话 exit在此之前,它永远不会被破坏。在这种特殊情况下,这不是问题,但如果例如b是一个带有析构函数的对象,它应该执行一些在程序外部可见副作用的操作,可能是这样。

您不应该调用exit(0)main 退出程序。只需使用 return 0;或者完全省略它,因为 main具体来说,没有 return 语句相当于 return 0; .


旁注:您不应该显式声明/定义不执行任何操作且不是 virtual 的析构函数。 ,如A::~A() {} 。如果您根本没有在类中声明析构函数,编译器将自动为您生成析构函数,并且行为完全相同。

手动声明析构函数无论如何都会对特殊成员函数的其他隐式生成产生影响,这可能会影响程序的性能,并且也使得始终遵循rule of 0/3/5变得更加困难。 .


My first question is that the object A(v) that added the the map, it should be deleted automatically when exit the scope?

A(v)是一个临时对象,将在完整表达式 a_[name] = A(v) 结束时被销毁.

Also, do I need to provide a copy constructor?

不,如果您不手动声明一个成员(与析构函数相同),则编译器会隐式声明一个成员,并且假设这是可能的,它将被定义为简单地复制每个成员。无论如何,这通常是您想要的。

My last question is that I did not create any object with "new", I shouldn't need to delete any.

是的,完全正确。

关于c++ - 内存泄漏,我不知道为什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70637008/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com