2011-07-04 17 views
6

私はMIDIファイルをLilypondのソースファイルに変換するプログラムを作成してC++を学んでいます。 私のプログラムは、MidiFileという名前のオブジェクトを作成するMIDIファイルパーサ、まだ実行されていないコードによって明らかにエラーが発生しました

  • で構成されています。
  • MidiFileオブジェクトを取り込み、それをLilypondソースに変換するコンバータ。

今日は、コンバータをコーディングを開始しました、と私はそれをテストしている間に奇妙なエラーが発生しました:例外がMIDIファイルにそのヘッダチャンクを意味HeaderError、より具体的に、スローされた後、プログラムが死にます期待通りではありません。それは奇妙に見えませんが、バグのコードの後に​​コードの行を追加した場合にだけこのエラーが表示されます!私はこのような優れた(私のメインで自分自身に

#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; 
} 

これはどのように可能か説明できません。誰かがアイデアやアドバイスを持っていれば、すべての助けが大いに評価されるでしょう:)私が他のクラスや機能のソースコードを投稿することができれば役に立ちます。

+4

メモリは呼び出さないコードのどこかに上書きのようなにおいがします。新しいローカル変数を宣言すると、スタックレイアウトが変更され、異なるものが上書きされます。 – Torp

+0

私にはスタックの破損のような音がしますが、どこでどのように見ることができません。 – Justin

+3

これは 'Parser :: Parser parser = Parser :: Parser();'という一時的な 'Parser'オブジェクトを作成し、それを' parser'にコピーするときに問題になる可能性があります。 'Parser parser;だけを試してください。 –

答えて

3

解決済み!コメントへのコメントで指摘されているように、それはある種のメモリ破損によって引き起こされた問題でした。示唆したように私は、メモリchecher(valgrindのを)使用し、それは本当に愚かな誤りだったことが判明:私は単に、forループで

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

のようなものを、変数を初期化するのを忘れ、これはその奇妙なエラーにつながりました。 - )iを0に初期化すると問題が解決され、プログラムはスタックまたはヒープのいずれかに配置されたParserオブジェクトで動作します。

私は同様の問題が発生し、プログラムのメモリ使用量を制御するメモリチェッカーを使用することをお勧めします。 valgrindを使用するのは簡単です:

valgrind --leak-check=yes yourProgram arg1 arg2 

ここで、arg1とarg2は、プログラムが必要とする(最終的な)引数です。

さらに、プログラムを-gフラグでコンパイルする(少なくともg ++では、他のコンパイラではわかりません)、valgrindはメモリリークが発生したコードラインでも通知します。

皆様のおかげで助けてくれました!

よろしく
マッテオ

+0

さらに、正しいフラグを使用して、Valgrindは初期化されていないメモリの使用状況を検出し、そのメモリがいつどこに割り当てられたかを伝えることができます。 – Novelocrat

関連する問題