[英]Delete char pointer not working in destructor
我有一个程序,向用户询问文本文件的名称,然后打开文本文件并对其进行填充(读取,写入),然后关闭文件并退出程序。
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;
并在file.close()
fileName被删除后将其放在ReadFile()
,为什么呢?
我的程序的其余部分工作正常,这就是为什么没有粘贴任何代码的原因。 我只是想摆脱任何内存泄漏,而fileName是我遇到的唯一麻烦,因此我只将代码粘贴到使用fileName的地方。
任何帮助表示赞赏。
附加信息:我正在使用Visual Studio编写此代码,并且正在使用内存泄漏检测。 这是它的输出:
检测到内存泄漏!
转储对象->
{132} 0x005D49A0的正常块,长40个字节。
数据:6E 61 6D 65 73 2E 74 78 74 00 CD CD CD CD CD CD CD
对象转储完成。
程序“ [10772] program1.exe:本机”已退出,代码为0(0x0)。
这就是为什么我怀疑delete []fileName;
没有用
同样,这就是int main()
样子
int main(){
Program abc;
abc.ReadFile();
}
哦,Program.h无法更改。 只有.cpp可以更改,这是我要求的一部分。
如果文件名仅在readFile中使用-那么我建议您从Program类中将其删除,并在该函数中使其成为自动变量:
void Program::ReadFile(void){
char fileName[40];
...
file.close();
// no delete [] necessary
}
您的问题可能与
因此,请勿将成员变量用作方法的自动变量。
如果必须具有该成员变量-将其更改为数组-不要分配它:
class Program {
private:
// char* filename;
char filename[40];
};
[UPDATE]
您的.h文件不正确-违反了三个规则(请参阅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];
您确定main
内容与此处的内容完全一样吗? 如果仅全局定义abc
,它将在内存转储报告内存泄漏后被释放,并且您可能会看到无效的报告! 您可以在析构函数中插入一个断点,并查看是否在析构函数之后或之前报告了内存泄漏
fileName
显然已被删除:析构函数中的代码如此表示。 但是,如果您未显示的代码多次调用ReadFile
,则该类将泄漏内存,因为对ReadFile
每次调用都会分配一个新的内存块,并覆盖指向前一个块的指针。
思考RAII:资源分配就是初始化。 在构造函数中,分配内存块。 在析构函数中,将其删除。 然后, ReadFile
不必担心分配块。
或者,甚至更好,按照@PiotrNycz的说明进行操作,然后将指针更改为数组。 无需动态分配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.