I have a number of mutually dependent classes that work OK when used within one single scope. Now I want to make instances of them work in several procedures/scopes. It is probably my lack of in-depth knowledge of C that gives me trouble to implement this well.
I'll first describe the (starting) situation that is working fine.
Here I instantiate class objects within a routine test_recorder()
void test_recorder(void) {
MIDISequencerGUINotifierText text_n;
AdvancedSequencer sequencer(&text_n);
MIDIRecorder recorder(&sequencer);
...
...
recorder.EnableTrack(1); //use a member of recorder object
...
... }
Now I want to use members of these classes in other functions. So I thought I would have to make instances of the classes globally accessible. I brought the first three lines in test_recorder to the global level, outside any function. The compiler accepted this trial, but at runtime I get an error without any clear clues in the post-mortem.
Then I decided to try defining pointers to the objects at the global level and instantiate the objects in test_recorder, using these pointers. Then I use the recorder object in a different routine:
AdvancedSequencer *ptrAdvancedSequencer;
MIDIRecorder *ptrMIDIRecorder;
void test_recorder( void ) {
AdvancedSequencer ptrAdvancedSequencer(&text_n);
MIDIRecorder ptrMIDIRecorder(&ptrAdvancedSequencer);
...
...}
void use_recorder(void){
...
...
ptrMIDIRecorder->EnableTrack(1);
...
...}
This leads to a runtime error with the top of the error trace looking as:
0x401a0d6c: vprintf at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdio/vprintf.c:30
0x400910ec: memcpy at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/machine/xtensa/memcpy.S:163
0x40091102: memcpy at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/machine/xtensa/memcpy.S:197
Of course I smell that this has something to do with how I handle the class objects. But I have not found a clue yet. Any suggestions are greatly appreciated!
CodePudding user response:
You're using name shadowing. That is, you have this:
AdvancedSequencer *ptrAdvancedSequencer;
void test_recorder( void ) {
AdvancedSequencer ptrAdvancedSequencer(&text_n);
...
}
These are NOT the same variable. They are different places in memory. Furthermore, once you exit this method, the data allocated inside the method is freed.
Instead, you have to do something like this:
void test_recorder( void ) {
ptrAdvancedSequencer = new AdvancedSequencer(&text_n);
...
}
And then use it as a pointer. However, you also then need somewhere that you later clean it up, as you've now allocated space.
CodePudding user response:
I worked out the suggestion by Jospeh Larson (thanks!). I post the working solution over here as it contains a small but important detail that was another discovery for me. For those that are more skilled it may be less of a surprise :-)
AdvancedSequencer *ptrAdvancedSequencer;
MIDIRecorder *ptrMIDIRecorder;
void test_recorder( void ) {
ptrAdvancedSequencer = new AdvancedSequencer(&text_n);
ptrMIDIRecorder = new MIDIRecorder(ptrAdvancedSequencer);
...
...}
void use_recorder(void){
...
...
ptrMIDIRecorder->EnableTrack(1);
...
...}
The detail is the missing & in new MIDIRecorder(ptrAdvancedSequencer) compared to the code in my question.