I have been trying to write a MIDI parser using C.
I did my research and learned so much about the MIDI file structure from multiple sources.
Here are some of the most useful ones (for the ones that are interested):
Using information from the sources above I wrote a really unoptimised MIDI parser. The aim of the current version is to simply print what events it encountered and save them on a file.
I have managed to parse through midi files [though I encountered a meta event that shouldn't exist (meta event 0x09)].
However, while implementing the save function I have seen that some midi files I had causes problems if I try to save them (Just parsing them works fine)(The program freezes for a while and returns non-zero value before finishing execution).
I think the problem could be associated with either the way I am allocating the memory or accessing it.
Here's the code (As I said, it's not pretty yet)):
_MtrkCD **MtrkDatas = (_MtrkCD **)(malloc(sizeof(_MtrkCD *)));
uint64_t i,j,k,p;
for (p=0;p<MthdData->tracks_count;p++){
MtrkDatas[p] = (_MtrkCD *)(malloc(sizeof(_MtrkCD)));
if(!_ReadMtrkChunk(midiFile,MtrkDatas[p],p,print)){
printf("Error reading MTrk Chunk. Bad MTrk.\n");
return 0;
}
}
^the part that allocates memory (posted because it's required)^
main.c
Here are the two example files I used(one works fine, the other causes problems):
home.mid(This file doesn't cause problems)
014-Theme03.mid(This is the one causing problems)
Here are the outputs when I run the program:
home Parsed.txt(Expected Output)
014-Theme03 Parsed.txt(What even is this?)
Again, I want to point out to some things that I have noticed:
Thank you all for your time. (Also I would be grateful if someone formatted the text better. I'm not very good at that as you can see.)
Here's the working code. I made a very simple mistake allocating memory for tracks. Thanks to Paul R for pointing out the mistake.
_MtrkCD **MtrkDatas = (malloc(sizeof(_MtrkCD *) * (MthdData->tracks_count)));
uint64_t i,j,k,p;
for (p=0;p<MthdData->tracks_count;p++){
MtrkDatas[p] = (malloc(sizeof(_MtrkCD)));
if(!_ReadMtrkChunk(midiFile,MtrkDatas[p],p,print)){
printf("Error reading MTrk Chunk. Bad MTrk.\n");
return 0;
}
}
In this line:
_MtrkCD **MtrkDatas = (_MtrkCD **)(malloc(sizeof(_MtrkCD *)));
you are only allocating an array of one pointer. So here you have undefined behaviour:
MtrkDatas[p] = (_MtrkCD *)(malloc(sizeof(_MtrkCD)));
whenever p > 0 (i.e. if tracks_count > 1 then you are in trouble).
You should probably change:
_MtrkCD **MtrkDatas = (_MtrkCD **)(malloc(sizeof(_MtrkCD *)));
to:
_MtrkCD **MtrkDatas = malloc(MthdData->tracks_count * sizeof(_MtrkCD *));
(note that the cast has been removed as it's redundant and potentially dangerous to cast the result of malloc and friends in C).