我想在类的构造函数中初始化一个(指向 a 的指针)map
。我编写的程序可以编译但由于段错误而在运行时失败。我可以通过为 map
动态分配内存来解决问题,但 Valgrind
会通知我内存泄漏。如何正确初始化类?
这是一个例子
#include <iostream>
#include <map>
#include <string>
#include <vector>
class MemoryLeak {
public:
MemoryLeak(std::vector<std::string>& inp) {
int i = 0;
std::map<std::string, int>* tmp = new std::map<std::string, int>;
for (std::string& s : inp) {
//(*problem_map)[s] = i++; // Line 12: causes a seg fault
(*tmp)[s] = i++;
}
problem_map = tmp; // Line 15: memory leak
}
std::map<std::string, int>* problem_map;
};
int main() {
std::vector<std::string> input{"a", "b"};
MemoryLeak mem = MemoryLeak(input);
for (auto const& it : *(mem.problem_map)) {
std::cout << it.first << ": " << it.second << "\n";
}
return 0;
}
当我取消注释
line 12
(并注释掉 Line 15
)时,程序编译但似乎发生了内存泄漏。有人可以告诉我我做错了什么吗?更合适的构造函数会是什么样子? 最佳答案
对于 段错误 :
您的指针 problem_map
在第 12 行未初始化。
这就是段错误的原因。
你不需要 tmp
你可以这样做:
problem_map = new std::map<std::string, int>;
for (std::string& s : inp) {
(*problem_map)[s] = i++;
}
现在对于泄漏,您有两个选择:
1) 添加析构函数、复制构造函数和复制赋值运算符(或将它们删除)。参见 three 规则
class MemoryLeak {
public:
~MemoryLeak() {
delete problem_map;
}
MemoryLeak(const MemoryLeak& ) = delete;
MemoryLeak& operator=(const MemoryLeak& ) = delete;
MemoryLeak(std::vector<std::string>& inp) {
int i = 0;
problem_map = new std::map<std::string, int>;
for (std::string& s : inp) {
(*problem_map)[s] = i++;
}
}
std::map<std::string, int>* problem_map;
};
2)不存储指针,而是存储 map
class MemoryLeak {
public:
MemoryLeak(std::vector<std::string>& inp) {
int i = 0;
for (std::string& s : inp) {
problem_map[s] = i++;
}
}
std::map<std::string, int> problem_map;
};
关于c++ - 在类的构造函数中初始化映射时如何避免内存泄漏?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56090788/