警告:出现这个问题是因为我必须处理一大堆糟糕的代码,没有适当的文档,这些代码是 6 年前由其他人作为研究项目编写的。显然,更好的解决方案是不通过适当的设计首先引起这些问题...
也就是说,问题是:摆脱这种情况的最佳方法是什么:
- 一个类在堆上分配内存,并在析构函数中释放它。
- 在某处,类的实例在全局范围内声明。
- 存在一个初始化此实例的函数。
- 该函数的返回值用于初始化静态变量。
- 全局范围变量在静态范围之外使用。
最小工作示例:
文件“myclass.h”:
#ifndef MYCLASS_H
#define MYCLASS_H
#include<vector>
using namespace std;
class myclass{
vector<int> *onTheHeap;
public:
myclass(int len=0){
onTheHeap = new vector<int>(len);
}
~myclass(){
delete onTheHeap;
}
};
#endif
文件“static_loader.cpp”
#include "class.h"
myclass existsForever;
int cause_static_global_creation(){
existsForever = myclass(5);
}
static int bootstrap = cause_static_global_creation();
和文件“main.cpp”:
#include "class.h"
extern myclass existsForever;
int main(){
return 0;
}
构建:
g++ -g -c static_loader.cpp
g++ -g main.cpp static_loader.o
并运行为:
valgrind --leak-check=full ./a.out
结果:当在退出处理程序下面的 main 中调用其析构函数时,该变量被释放,但也是在 static_loader 下面的 main 中的 static_initialization_and_destruction_0 函数中被调用!
有没有一种方法可以确保这些变量准确地释放一次而不涉及大量重构代码?在我必须使用的库中,有几十个这种模式的实例......
编辑:
添加函数:
void operator=(myclass other){
delete this->onTheHeap;
this->onTheHeap = other.onTheHeap;
}
和
myclass(const myclass& other){
this->onTheHeap = new vector<int>(*(other.onTheHeap));
}
不改变行为。
第二次编辑:
myclass& operator=(const myclass& other){
delete this->onTheHeap;
this->onTheHeap = new vector<int>(*(other.onTheHeap));
return *this;
}
解决所有问题。无论如何,我的图书馆有这样的来源内存泄漏,但我不再确定如何重现它。至少不是这样,也感谢重构等方面的建议!
最佳答案
你的假设被打破了。 myclass existsForever;
不是由 cause_static_global_creation
初始化的,而是由 myclass::myclass
初始化的。相反,cause_static_global_creation
为已初始化的对象分配一个值。
由于该类(class)违反了三原则,因此作业出现问题也就不足为奇了。
关于c++ - 解决由全局静态变量引起的内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13011474/