多次使用动态字符数组后出现未知崩溃


执行动态内存时,程序崩溃的主要原因是什么?

我有一个类,在.h文件中定义了以下公共指针:

char *data;

我的程序有一个主要功能,在这里我依次创建这个类的对象,在这个创建中我做内存部分:

data = new char[dataSize];

主函数执行一次(对象创建10次),效果非常好。然而,当我再次运行主函数时(没有关闭程序),有一段时间指令data=new char[dataSize]会使程序崩溃(执行突然结束,所以我无法调试或查看任何内容)。

顺便说一下,每次创建对象时(在内存部分之前),指针都会初始化为NULL。

这就是代码。首先,主要功能,使用不同的对象执行20次:

CBinFileHwd validEpsData1;
validEpsData.loadFile(lpcTheFile3,dwFileSize,FT_BIT);

因此,函数的下一行将与上面相同,但它将不是validEpsData1,而是validEpsDData2,最多18次(validEpsData 17)。

类代码(.c):

CBinFileHwd::CBinFileHwd()
{
status = FILE_NOT_LOADED;
fileType = FT_UNKNOWN;
data = NULL;
currentPos = 0;
dataSize = 0;
}
CBinFileHwd::~CBinFileHwd()
{
if (data!=NULL) {
delete [] data;
data= NULL;
}
fileType = FT_UNKNOWN;
status = FILE_NOT_LOADED;
}
int CBinFileHwd::loadFile(const char *fileName, const unsigned long int &maxSize, const E_FILE_TYPE &fType)
{
// Open input file
int fd = open(fileName,O_RDONLY | O_BINARY);
if (fd < 0) {
char  logString[1024];
sprintf(logString,"Error opening file %s",fileName);
logMessage(logString, false, false, false);
fileType = FT_UNKNOWN;
status = FILE_NOT_LOADED;
return -1;
}
dataSize = lseek(fd,0,SEEK_END);
lseek(fd,0,SEEK_SET);
if (maxSize < dataSize) {
dataSize = maxSize;
}
data = new char[dataSize];
unsigned long int dataRead = 0;
while (dataRead < dataSize){
dataRead += read(fd, &data[dataRead], BLOCK_SIZE);
}
// Close file
close(fd);
status = FILE_LOADED;
fileType = fType;
if (maxSize != dataSize) {
return 1;
}else{
return 0;
}
}

类代码(.h):

typedef enum{FT_BIT,FT_INT,FT_DOUBLE, FT_UNKNOWN} E_FILE_TYPE;
class CBinFileHwd
{
private:
static const int BLOCK_SIZE = 4096;
typedef enum{FILE_NOT_LOADED, FILE_LOADED} E_STATUS;
E_STATUS status;
E_FILE_TYPE fileType;
char *data;
unsigned long int currentPos;
unsigned long int dataSize;
public:
CBinFileHwd();
~CBinFileHwd();
int loadFile(const char *fileName, const unsigned long int &maxSize, const E_FILE_TYPE &fType);
};

这可能是因为:

  1. 由于为此类编写的复制构造函数和赋值运算符不正确,因此双重释放。因此,多个对象可能指向相同的动态内存分配。如果您的输入数据大小不超过128字节(即您的分配大小),那么构造函数和析构函数看起来是可以的。

  2. 这也可能是因为程序中的堆内存损坏,而这段代码可能只是其他地方实际损坏的牺牲品/后遗症。

然而,一旦您发布代码,我们可能会更好地找出崩溃的原因。

由于我上面的回答中提到的第1点,您的程序似乎正在崩溃。

似乎还有一个内存泄漏问题,因为"data"是类的成员变量,一旦您多次调用loadFile()函数,数据就会被新的内存地址覆盖。这也是代码中的一个大问题。

您可能希望在分配"数据"内存之前进行检查。

int CBinFileHwd::loadFile
{
...................
if(data != nullptr) {
data = new char[dataSize];
}
unsigned long int dataRead = 0;
..........................
}

尝试:

dataRead += read(fd, (data+dataRead), BLOCK_SIZE);

您是否意外地向同一个变量"validEpsData"赋值了18次,在这种情况下,内存泄漏。你在哪里声明了这个变量?

validEpsData.loadFile(lpcTheFile3,dwFileSize,FT_BIT);

应该是:

validEpsData1.loadFile(lpcTheFile3,dwFileSize,FT_BIT);
......
validEpsData18.loadFile(lpcTheFile3,dwFileSize,FT_BIT);

析构函数将不会被调用,直到您离开main()的范围,或者换句话说,退出程序

最新更新