为什么这个二进制输出代码会导致内存泄漏

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.

中调用基类析构函数