I am working on a project where I need to delete my arrays in the loop in order to not run out of SRAM.
My problem :
I initialise my array before the setup
int* A = new int[300];
I fill it in the loop. It's an array of notes coming from a MIDI keyboard. I have to initalise the array before the loop because the function that fills this array (function called in the loop) have to be before the loop (that's how it's supposed to be in the MIDI library).
It looks like that :
initialisation of the array A of notes
function f called when I press a key. It fills the array A with the note and moves towards the next line.
loop. It calls function f each time a key is pressed.
I do a lot of stuffs in the loop an delete the array when it is not needed anymore : delete A;
The whole program works fine the first time.
Problem : When the loop restarts, the array of notes fill itself again (everything's fine) but the program stops when it's time to delete A again. (I moved the delete and yes, the program always stops at this precise time.)
Is there any way I can 'reinitialise' my table A at the beginning of the loop so that the delete can work at the end of the loop ?
Other hints about what's happening ?
Where’s the code?
(Sorry be so brutal, but it’s about the third time today I’ve had to state the obvious)
I can’t really see why you would ever want to use new/delete in such a simple scenario.
The main page of code is 719 lines. I thought it would be nice to simplify the problem. If I cut everything I think is not related it would give :
#include <Arduino.h>
#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
int longAcquisition=300;
byte* notes = new byte[longAcquisition];
int i=0;
void MyNoteOn(byte channel, byte pitch, byte velocite) { //Function called when a key is pressed
notes[i]=pitch;
i=i+1;
}
void setup() {
Serial1.begin(31250);
MIDI.begin(1);
MIDI.setHandleNoteOn(MyNoteOn); //MyNoteOn will be the function called when a key is pressed
}
void loop() {
i=0;
while(acquisition==HIGH){ //acquisition is a button
MIDI.read(); //Function that watch MIDI inputs and calls MyNoteOn when a key is pressed
}
// end of acquisition
sizeNotes=i;
// Calculations with my array
delete[] notes;
//Calculations
}
notes is initialised before the loop because it is used by the function MyNoteOn that is defined before the loop.
I need to deallocate it cause otherwise my program runs out of memory before the end of the loop …
It is highly likely that I could have written it in another less SRAM-consuming way, but I don’t see how.
I am pretty sure the rest of the code is fine, cause everything works as exepected during the first passage into the loop.
During the first passage in the loop, the array seems to accept the delete, but in the second passage, I fill it again, the computation goes on until the delete line where it stops.
I use other arrays that I create in my loop and delete later and it works fine even in the second passage in the loop.
If you're just going to come around in loop and write up another array, then there's no need to delete it. Just write over it. Set i back to 0 and write over the array you already have.
Delta_G:
If you're just going to come around in loop and write up another array, then there's no need to delete it. Just write over it. Set i back to 0 and write over the array you already have.
If I do that, I run out of sram for the last part of my calculations. Even the first passage in the loop doesn't finish.
ced13:
her arrays that I create in my loop and delete later and it works fine even in the second passage in the loop.
That sounds as if you are fragmenting the heap like a Swiss-style cheese, and at some point you have many, but small fragments of free RAM available, and none of them is big enough to assign a new array.
Do you have error checking in your sketch?
Error checking whether dynamical memory allocations are OK or fail at runtime?
int* A = new int[300];
if (A==NULL) ... // memory allocation failed
PaulS:
If you don't have room for a static array, you don't have room for a dynamic array. It is silly to think that you do.
It may be uninformed but not silly, please be friendly.
I have the space for the whole array, but then I creates other arrays based on this one, and do calculations on the notes. That's why I deallocate my first array, to get enough sram to do other calculations and manipulate other arrays. I am not an Arduino expert, maybe I didn't understand your sentence, tell me if I'm still wrong.
PaulS:
Post your real code. Otherwise, you look like a doofus.
I can't since it's more than 9000 caracters.
PaulS:
while(acquisition==HIGH){ //acquisition is a button
MIDI.read(); //Function that watch MIDI inputs and calls MyNoteOn when a key is pressed
}
If acquisition IS HIGH, how is it going to change while the while loop is running?
I was too lazy to introduce the declaration of the button and to add ' acquisition=digitalRead(bouton_acquisition);' but it's not the point, because this part works fine the first time it goes into the loop.
jurs:
That sounds as if you are fragmenting the heap like a Swiss-style cheese, and at some point you have many, but small fragments of free RAM available, and none of them is big enough to assign a new array.
Do you have error checking in your sketch?
Error checking whether dynamical memory allocations are OK or fail at runtime?
int* A = new int[300];
if (A==NULL) ... // memory allocation failed
No I don't do this, but I will. Is there a way to re-arrange memory to get bigger fragments ?
But in my case, the program stops when I try to delete an array. It looks like I have enough memory to complete a loop when I delete arrays after they become useless for my calculations.
Also, I don't understand how my array of notes can be filled again in the 2nd loop even if it has been deallocated in the first one and not reallocated. (code before the setup is only performed once, right ?)
It is like if it still exists and can be filled with new notes, but at the same time it can't be deallocated a second time.
I record notes from a keyboard, I fill vectors with notes, times, velocity. Then I extract left hand, right hand, monophonic notes. I compute features (functions on other files) and make an association with ingredients with fuzzy rules (on other files). Then I realise the cocktail with pumps.
The code is a bit messy, it’s my first project on arduino. The main page deals with buttons, leds and the different tables of notes. Comment are in french as well. Not sure you will have the courage to go through this.
Otherwise I could just reset the board at the end of the loop. From an exterior point of view, that's the same. Only problems, when the arduino is off, pumps commands are not controlled and it sucks my beverages out for a few milliseconds.. Could probably solve this on the hardware part but I don't want to go that way.
If you're worried about RAM usage, then why are you throwing RAM away on constant strings? Wouldn't that be a more obvious place to start trying to fix this?
Serial.print(" Rhum blanc : "); // wastes 15 bytes of RAM storing the constant string
Serial.print(F(" Rhum blanc : ")); // uses 0 bytes of RAM to store the constant string
It's the mega. Yep I know it consumes lot of memory, but I need those 300 notes. I understand that it's not good to allocate it globally and use it in the loop but I don't see other way to do this.
I used to have static arrays but when I ran out of memory, I decided to make them dynamic so that I can deallocate them. Otherwise I was limited to 50 notes, that's quite poor.
I should probably have doing that on raspberry, but I didn't know at that time.
Is there a way to re-allocate them in the beginning of the loop so that I can delete them more than once ?
Maybe with the space I freed from the serial.print I would have enough space to have static arrays but I'm not so sure.