我对c ++很新。我正在将文件的内容读入这样的结构:
struct wavObj {
uint8_t *dataBuffer; // the data
int readFile( const char *filePath );
};
int wavObj::readFile( const char *filePath ) {
FILE *file = NULL; // File pointer
file = fopen( filePath, "rb" );
dataBuffer = new uint8_t[data_Size];
fread(dataBuffer, data_Size, 1, file);
fclose(file);
return 0;
}
我是否需要在某处使用delete运算符来删除wavObj.dataBuffer?当程序结束时,这个结构会被破坏,内存分配也会被破坏吗?如果没有,我可以创建一个使用删除操作符的析构函数吗?
答案 0 :(得分:0)
您应该显式声明析构函数以释放内存,否则可能导致溢出。
当你的程序结束时,分配的内存不会被标记为空闲,也不会成为免费内存池的一部分。您需要明确删除已分配的内存。
但有了这个,你应该遵循 RARLE OF THREE 以及
答案 1 :(得分:0)
正如评论中所提到的,更好的方法是使用std::vector<>
。
struct wavObj {
std::vector<uint8_t> dataBuffer; // the data
int readFile( const char *filePath );
};
int wavObj::readFile( const char *filePath ) {
//...
dataBuffer.clear();
dataBuffer.resize(data_Size);
fread(&dataBuffer[0], data_Size, 1, file);
//...
}
这避免了定义析构函数,复制构造函数和赋值运算符(以及移动变体)的需要。这有时称为Rule of Three(或Rule of Three-or-Four-or-Five):
如果您将dataBuffer
作为接收动态分配的裸指针,那么您需要添加更多代码以在确定时正确获取内存。大多数程序员都知道要清理的地方是析构函数。
struct wavObj {
uint8_t *dataBuffer; // the data
int readFile( const char *filePath );
~wavObj () { delete [] dataBuffer; }
};
但是,规则三将规定还需要定义复制构造函数以正确复制正在复制的对象的指针,并定义一个赋值运算符以正确清理本地副本并正确复制指针右手边。如果不这样做,可能会导致由悬空指针引起的未定义行为。由于额外的复杂性,如果可能的话,最好完全避免这个问题。