为什么这个二进制输出代码会导致内存泄漏
Why is this binary output code causing a memory leak
我是 C++ 的新手,我正在尝试输出 wave 文件。我在 C# 和 Java 中使用二进制文件都取得了成功,但我对 C++ 还不太满意。我知道数组和 objects 通常应该在堆上创建。
字符串和第一个没问题getter
每当它到达基数 class 的第二个 getter 时,它就会耗尽内存。
这个 class 称为 waveWriter,它扩展了一个 class 称为 WaveFormat,它包含 getters
WaveWriter header:
class WaveWriter : WaveFormat {
private:
std::string fileName;
public:
WaveWriter(uint16_t channels, uint32_t sampleRate,
uint16_t bitsPerSample, double* lSampleData,
uint32_t lSampleLength, double* rSampleData,
uint32_t rSampleLength, bool isFloat, std::string outputName);
~WaveWriter();
void writeWave() {
std::ofstream myFile;
myFile = std::ofstream(fileName, std::ios::out | std::ios::binary);
// write the header
// sGroupID
myFile << S_GROUP_ID_HEADER;
// dwfilelength
myFile.write(reinterpret_cast<const char *> (GetDwFileLength()),
sizeof (GetDwFileLength()));
// sRiffType
myFile << S_RIFF_TYPE;
// write the format
// sGroupID
myFile << S_GROUP_ID_FORMAT;
// dwChunkSize
myFile.write(reinterpret_cast<const char *> (GetDwFormatChunkSize()),
sizeof (GetDwFormatChunkSize()));
// wFormatTag
........ blah blah blah
// close file
myFile.close();
return;
}
};
此 class 的 cpp:
WaveWriter::WaveWriter(uint16_t channels, uint32_t sampleRate,
uint16_t bitsPerSample, double* lSampleData,
uint32_t lSampleLength, double* rSampleData,
uint32_t rSampleLength, bool isFloat, std::string outputName) :
WaveFormat(channels, sampleRate, bitsPerSample,
lSampleData, lSampleLength, rSampleData,
rSampleLength, isFloat) {
outputName.append(".wav");
this->fileName = outputName;
}
WaveWriter::~WaveWriter() {
this->~WaveFormat();
}
Header for WaveFormat 包含私有变量构造函数和 getters 像这样访问私有变量:
public:
uint16_t GetCbSize() {
return cbSize;
}
uint32_t GetDwAvgBytesPerSec() {
return dwAvgBytesPerSec;
}
uint32_t GetDwChannelMask() {
return dwChannelMask;
}......
这是根据您的函数名称推测的,但我认为这段代码:
myFile.write(reinterpret_cast<const char *> (GetDwFileLength()),sizeof (GetDwFileLength()));
不正确。假设 GetDwFileLength()
return 大小作为值,将其转换为 const char *
是不正确的。您需要将其保存在另一个参数中,并 post 要转换的地址。像这样:
auto val = GetDwFileLength();
myFile.write(reinterpret_cast<const char *> (&val), sizeof (val));
我在你的代码中多次看到类似的错误。这个错误会造成无效的内存访问。
此外,您应该使用 virtual
基析构函数,而不是从派生的 class 调用基析构函数。永远不要在派生 class.
中调用基类析构函数
我是 C++ 的新手,我正在尝试输出 wave 文件。我在 C# 和 Java 中使用二进制文件都取得了成功,但我对 C++ 还不太满意。我知道数组和 objects 通常应该在堆上创建。
字符串和第一个没问题getter
每当它到达基数 class 的第二个 getter 时,它就会耗尽内存。 这个 class 称为 waveWriter,它扩展了一个 class 称为 WaveFormat,它包含 getters
WaveWriter header:
class WaveWriter : WaveFormat {
private:
std::string fileName;
public:
WaveWriter(uint16_t channels, uint32_t sampleRate,
uint16_t bitsPerSample, double* lSampleData,
uint32_t lSampleLength, double* rSampleData,
uint32_t rSampleLength, bool isFloat, std::string outputName);
~WaveWriter();
void writeWave() {
std::ofstream myFile;
myFile = std::ofstream(fileName, std::ios::out | std::ios::binary);
// write the header
// sGroupID
myFile << S_GROUP_ID_HEADER;
// dwfilelength
myFile.write(reinterpret_cast<const char *> (GetDwFileLength()),
sizeof (GetDwFileLength()));
// sRiffType
myFile << S_RIFF_TYPE;
// write the format
// sGroupID
myFile << S_GROUP_ID_FORMAT;
// dwChunkSize
myFile.write(reinterpret_cast<const char *> (GetDwFormatChunkSize()),
sizeof (GetDwFormatChunkSize()));
// wFormatTag
........ blah blah blah
// close file
myFile.close();
return;
}
};
此 class 的 cpp:
WaveWriter::WaveWriter(uint16_t channels, uint32_t sampleRate,
uint16_t bitsPerSample, double* lSampleData,
uint32_t lSampleLength, double* rSampleData,
uint32_t rSampleLength, bool isFloat, std::string outputName) :
WaveFormat(channels, sampleRate, bitsPerSample,
lSampleData, lSampleLength, rSampleData,
rSampleLength, isFloat) {
outputName.append(".wav");
this->fileName = outputName;
}
WaveWriter::~WaveWriter() {
this->~WaveFormat();
}
Header for WaveFormat 包含私有变量构造函数和 getters 像这样访问私有变量:
public:
uint16_t GetCbSize() {
return cbSize;
}
uint32_t GetDwAvgBytesPerSec() {
return dwAvgBytesPerSec;
}
uint32_t GetDwChannelMask() {
return dwChannelMask;
}......
这是根据您的函数名称推测的,但我认为这段代码:
myFile.write(reinterpret_cast<const char *> (GetDwFileLength()),sizeof (GetDwFileLength()));
不正确。假设 GetDwFileLength()
return 大小作为值,将其转换为 const char *
是不正确的。您需要将其保存在另一个参数中,并 post 要转换的地址。像这样:
auto val = GetDwFileLength();
myFile.write(reinterpret_cast<const char *> (&val), sizeof (val));
我在你的代码中多次看到类似的错误。这个错误会造成无效的内存访问。
此外,您应该使用 virtual
基析构函数,而不是从派生的 class 调用基析构函数。永远不要在派生 class.