Hallo,
wie der Titel schon sagt, habe ich ein Problem mit malloc() und free.
Ich teste gerade auf dem STK600 Programmteile, die ich eigentlich in
einem größeren Programm verwenden will. Der Controller ist ein
Atmega2560 mit 32k externem Ram.
Ich will jetzt niemandem zumuten, sich das Programm in Einzelnen
anzusehen. Daher beschreibe ich das mal kurz.
In der main steht folgendes:
1 | XMCRA =0;
|
2 | XMCRA |= (1<<SRE) |(1<<SRW11)|(1<<SRW10) ;
|
3 | XMCRB = 0;
|
Der Linker wird folgendermassen aufgerufen:
1 | -mrelax -ffunction-sections -Wl,--defsym=__heap_start=0x802200,--defsym=__heap_end=0x807fff
|
In dem Programm rufe ich eine Funktion auf. In der werden verschiedene
Arrays und Strukturen über malloc reserviert.
1 | char* recbuf = (char*)malloc(sizeof(RECBUFFER_SIZE));
|
2 | char* sendbuf = (char*)malloc(sizeof(SENDBUFFER_SIZE));
|
Am Ende der Funktion wird der Speicher wieder freigegeben.
1 | free(recbuf);
|
2 | recbuf = NULL;
|
3 | free(sendbuf);
|
4 | sendbuf = NULL;
|
In dieser Funktion wird wird eine weitere Funktion aufgerufen, die
sendbuf als Parameter hat und über den Uart den Inhalt von sendbuf
sendet.
Beim ersten Aufruf der ersten Funktion funktioniert das auch
einwandfrei. Beim zweiten Aufruf stimmt der Wert, der in sendbuf
geschrieben wird, in der ersten Funktion noch überein, aber nicht in der
Funktion, die den Inhalt von sendbuf über den Uart senden soll. Ich habe
mir an der Stelle, wo sendbuf beschrieben wird, das auch mit printf
anzeigen lassen. Dort steht es aber noch drin. Aber nicht mehr in der
Funktion, die den Inhalt senden soll.
Nach dem malloc steht folgendes:
1 | if (!recbuf) {
|
2 | printf("Sendbuffer Memory allocation error in messdaten_senden\n");
|
3 | return;
|
4 | }
|
Dasselbe steht auf für sendbuf. Allerdings scheint das zu funktionieren.
Denn der Fehler wird mir nicht angezeigt.
RECBUFFER_SIZE und SENDBUFFER_SIZE sind mit #define als 255 im Programm.
Zum Testen habe ich RECBUFFER_SIZE mal auf 25 gesetzt. Der Fehler blieb.
Immer beim zweiten Mal, funktioniert es nicht mehr.
Wenn ich die Variablen global anlege und nicht über malloc. Dann kann
ich die Funktionen ohne Fehler bis zur Unendlichkeit aufrufen. Das läuft
einwandfrei.
Dasselbe, wenn ich die Variablen lokal in der ersten Funktion anlege.
Beim Versuch das weiter einzugrenzen, habe ich das dann nochmal malloc
verwendet und versehentlich vergessen die Aufrufe von free am Ende der
Funktion auszukommentieren. Dabei habe ich festgestellt, dass das dann
auch einwandfrei läuft. Ich vermute allerdings, da der Speicher immer
neu reserviert wird, dass dann irgendwann ein Fehler auftaucht, weil
kein freier Speicher mehr vorhanden ist. Nehme ich free wieder rein,
habe ich wieder mein Problem.
Ich könnte das Ganze natürlich mit lokalen Variablen machen. Das Problem
ist aber, dass das später unter einem Multitasking-BS (ucos) laufen soll
und dann müsste der Stack dementsprechend gross angelegt werden, so dass
selbst der Atmega2560 an seine Grenzen kommen würde. Daher wäre mir der
Weg mit malloc lieber.
Den Ram habe ich getestet mit einem Testprogramm. Da wird kein Fehler
gemeldet. An der Hardware liegt es wohl nicht.
Hat jemand eine Idee oder Tip, woran es liegen könnte?
Ich hoffe, ich konnte das einigermaßen vernünftig erklären.
Vielen Dank und viele Grüße
Andreas