我有一个程序,我向用户询问文本文件的名称,我打开文本文件做它的东西(读,写),然后我关闭文件并退出程序。
Program.h
class Program
{
char* fileName;
public:
Program();
~Program();
void ReadFile(void);
};
Program.cpp
Program::Program(){
//contstructor
fileName=NULL;
}
Program::~Program(){
cout << "in destructor" ;
delete []fileName;
}
void Program::ReadFile(void){
fileName = new char[40];
cout <<"Please enter the name of the file to open: ";
cin.clear();
cin.getline(fileName, 40);
ifstream file (fileName);
if(file.is_open()){
//do stuff
}
file.close();
}
现在,当我将delete []fileName;
放入析构函数中时,它会在屏幕上输出“”in destructor“,但fileName不会被删除。如果我将delete []fileName;
放入ReadFile()
在file.close()
fileName被删除之后。为什么会这样?
我的程序的其余部分完美地工作,这就是为什么没有粘贴代码的原因。我只是试图消除任何内存泄漏,fileName是唯一一个我遇到问题的因此,因此我只粘贴了使用fileName的代码。
感谢任何帮助。
其他信息: 我正在使用Visual Studio编写此内容并使用内存泄漏检测。这是它输出的内容:
检测到内存泄漏!
倾倒物体 - &gt;
{132}正常阻塞位于0x005D49A0,长度为40个字节 数据:6E 61 6D 65 73 2E 74 78 74 00 CD CD CD CD CD CD 对象转储完成。
程序'[10772] program1.exe:Native'已退出,代码为0(0x0)。
这就是为什么我怀疑delete []fileName;
无效。
此外,这是int main()
的样子
int main(){
Program abc;
abc.ReadFile();
}
哦,并且Program.h无法更改。只有.cpp可以改变它是我的要求的一部分。
答案 0 :(得分:3)
如果filename只在readFile中使用 - 那么我建议你从Program类中删除它并使它在该函数中自动变量:
void Program::ReadFile(void){
char fileName[40];
...
file.close();
// no delete [] necessary
}
您的问题可能与
有关因此,不要将您的成员变量用作方法的自动变量。
如果必须将此成员变为可变 - 将其更改为数组 - 请不要分配它:
class Program {
private:
// char* filename;
char filename[40];
};
[UPDATE]
您的.h文件不正确 - 它违反了规则3(请参阅http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)) - 复制构造函数和赋值运算符丢失。因此,请注意不要以任何方式复制您的Program类,否则无法更改此标题。
更新后,程序中只缺少一件事:
在readFile的开头添加delete[] filename
:
void Program::ReadFile(void){
delete [] filename;
fileName = new char[40];
或(更好) - 每次调用readFile时都不要重新分配:
void Program::ReadFile(void){
if (!filename)
fileName = new char[40];
或(最佳) - 仅在构造函数中分配此内存:
Program::Program() : filename(new char[40]) {}
void Program::ReadFile(void){
// fileName = new char[40];
答案 1 :(得分:1)
您确定main
与此处发布完全一致吗?如果您只是全局定义abc
,它将在内存转储报告内存泄漏后释放,您可能会看到无效的报告!您可以在析构函数中插入断点,并查看在析构函数之后或之前是否报告了内存泄漏
答案 2 :(得分:0)
fileName
:析构函数中的代码是这样说的。但是如果您没有多次调用代码ReadFile
,则该类将泄漏内存,因为每次调用ReadFile
都会分配一个新的内存块并覆盖指向前一个块的指针。
认为RAII:资源分配是初始化。在构造函数中,分配内存块。在析构函数中,删除它。然后ReadFile
不必担心分配块。
或者,甚至更好,就像@PiotrNycz所说,并将指针更改为数组。无需动态分配。