Ошибка, видимо, вызвана еще не выполненным кодом - PullRequest
6 голосов
/ 04 июля 2011

Я изучаю c ++, написав программу для преобразования MIDI-файлов в Lilypond исходные файлы.Моя программа состоит из двух основных частей:

  • анализатор 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;
}

С моим 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;
}

Я не могу объяснить, как это возможно.Так что, если у кого-то есть идеи или советы, вся помощь будет принята с благодарностью :) Если это полезно, я могу опубликовать исходный код для других классов и / или функций.

1 Ответ

3 голосов
/ 05 июля 2011

Решено! Как отмечено в комментариях к вопросу, это была проблема, вызванная каким-то повреждением памяти. Как и предполагалось, я использовал проверку памяти (valgrind) и обнаружил, что это действительно глупая ошибка: я просто забыл инициализировать переменную в цикле for, что-то вроде

for (int i; i < limit ; i++)

и это привело к этой странной ошибке :-) Инициализация i в 0 решила проблему, и теперь программа работает с объектом Parser, помещенным либо в стек, либо в кучу.

Поэтому я предлагаю другим людям, сталкивающимся с подобными проблемами, использовать средство проверки памяти, чтобы контролировать использование памяти их программой. Использовать valgrind действительно просто:

valgrind --leak-check=yes yourProgram arg1 arg2

где arg1 и arg2 - (возможные) аргументы, необходимые вашей программе.

Помимо компиляции вашей программы с флагом -g (по крайней мере, на g ++, я не знаю, на других компиляторах), valgrind также сообщит вам, в какой строке кода произошла утечка памяти.

Спасибо всем за помощь!

Привет
Маттео

...