由于尚未执行的代码显然引发了错误

Mat*_*llo 6 c++ memory-leaks exception

我正在通过编写将MIDI文件转换为Lilypond源文件的程序来学习c ++ .我的程序由两个主要部分组成:

  • 一个MIDI文件解析器,它创建一个名为MidiFile的对象.
  • 获取MidiFile对象并将其转换为Lilypond源的转换器.

今天我开始对转换器进行编码,当我测试它时发生了一个奇怪的错误:程序在抛出异常后死亡,更具体地说是HeaderError,这意味着MIDI文件中的标题块不是预期的.它似乎并不奇怪,但只有在我的错误代码之后添加一行代码时才出现此错误!我添加了main()函数来更好地解释自己

#include <iostream>
#include "midiToLyConverter.hpp"

int main(){

            // a queue to store notes that have not yet been shut down
    using MidiToLyConverter::Converter::NoteQueue;
            // representation of a note
    using MidiToLyConverter::Converter::Note;
            // the converter class
    using MidiToLyConverter::Converter::Converter;
            // the midifile class
    using Midi::MidiFile;
            // representation of a midi track
    using Midi::MidiTrack;
            // representation of a midi event
    using Midi::MidiEvents::Event;

    Parser::Parser parser = Parser::Parser(); // parser class
    parser.buildMidiFile(); // builds the midi file from a .mid
    Midi::MidiFile* midiFile = parser.getMidiFile(); // gets the MidiFile object

    // iterates over all the tracks in the MidiFile
    while(midiFile->hasNext()){
        std::cout<< "==========\n";
        MidiTrack* track = midiFile->nextTrack();
        // iterates over all events in a track
        while(track->hasNext()){
            Event* event = track->nextEvent();
            if (event->getEventType() == Midi::MidiEvents::NOTE_ON ||
                event->getEventType() == Midi::MidiEvents::NOTE_OFF
            )
                // print the event if it's a note on or off
                event->print();
        }
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用我的main(),一切正常,但是,如果我在buildMidiFile和while循环之间添加一些东西,函数buildMidiFile会抛出异常!即使这是一个完全不相关的指令!

#include <iostream>
#include "midiToLyConverter.hpp"

int main(){

    using MidiToLyConverter::Converter::NoteQueue;
    using MidiToLyConverter::Converter::Note;
    using MidiToLyConverter::Converter::Converter;
    using Midi::MidiFile;
    using Midi::MidiTrack;
    using Midi::MidiEvents::Event;


    Parser::Parser parser = Parser::Parser(); // parser class
    parser.buildMidiFile(); // THE EXCEPTION IS THROWN HERE
    Midi::MidiFile* midiFile = parser.getMidiFile(); // gets the MidiFile object

            // adding this causes the exception to be thrown by the function
            // buildMidiFile() called 5 lines above!
    std::vector<bool>* vec = new std::vector<bool>();

    // iterates over all the tracks in the MidiFile
    while(midiFile->hasNext()){
        std::cout<< "==========\n";
        MidiTrack* track = midiFile->nextTrack();
        // iterates over all events in a track
        while(track->hasNext()){
            Event* event = track->nextEvent();
            if (event->getEventType() == Midi::MidiEvents::NOTE_ON ||
                event->getEventType() == Midi::MidiEvents::NOTE_OFF
            )
                // print the event if it's a note on or off
                event->print();
        }
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我无法解释自己这是如何可能的.因此,如果有人有想法或建议,所有的帮助将不胜感激:)如果它有用,我可以发布其他类和/或功能的源代码.

Mat*_*llo 3

解决了!正如对该问题的评论中指出的那样,这是由某种内存损坏引起的问题。正如建议的那样,我使用了内存检查器(valgrind),发现这是一个非常愚蠢的错误:我只是忘记在 for 循环中初始化变量,比如

for (int i; i < limit ; i++)
Run Code Online (Sandbox Code Playgroud)

这导致了那个奇怪的错误:-)将 i 初始化为 0 解决了问题,现在程序使用放置在堆栈或堆上的 Parser 对象进行工作。

因此,我建议遇到类似问题的其他人使用内存检查器来控制其程序的内存使用情况。使用 valgrind 非常简单:

valgrind --leak-check=yes yourProgram arg1 arg2
Run Code Online (Sandbox Code Playgroud)

其中 arg1 和 arg2 是程序所需的(最终)参数。

此外,使用 -g 标志编译你的程序(至少在 g++ 上,我不知道在其他编译器上),valgrind 还会告诉你在哪一行代码发生了内存泄漏。

感谢大家的帮助!

问候
马泰奥