Hallo,
ich habe eine Funktion, die bekommt einen Pointer auf einen
Speicherbereich übergeben, in welchem sich eigentlich nur ein String
befindet.
Innerhalb der Funktion erzeuge ich nun einen neuen Pointer, der beim
Beginn der ursprünglichen Pointeradresse ansetzt.
/*... ein paar Aktionen mit dem RecPointer, Auslesen und Setzen betimmter Bytes im Datenstrom...*/
10
11
//anschließend:
12
free(RecPointer);
13
}
Nun ist das Problem:
ich erhalte Errormeldungen vom Typ Memleak.
Warum ist das so, wie kann ich diese umgehen, was hätte ich hier anders
machen müssen?
Ich dachte ich erzeuge erstmal nur einen Pointer, der auf die gleiche
Adresse von Buf zeigt... und ggf. kleiner ist, weil ich nur die strlen
von buf haben will... oder nicht?
> char* RecPointer =
Dein Pointer ist eine stinknormale lokale Variable.
> free(RecPointer)
Diese lokale Variable musst/darfst/kannst du nicht freigeben!
Das passiert automatisch.
Der vorher definierte Pointer verfällt beim verlassen der Funktion.
Wenn du auch den Speicherbereich freigeben willst, auf den der Pointer
zeigt, dann....
Aber das sehe ich hier nicht.
Memleak schrieb:> Ich dachte ich erzeuge erstmal nur einen Pointer
malloc "erzeugt" keine Pointer. malloc fordert dynamischen Speicher an,
und gibt als Ergebnis einen Pointer zurück, der darauf zeigt.
Wenn Du den Pointer wegwirfst (was Du mit Deiner Zuweisung unweigerlich
machst), geht der per malloc angeforderte Speicher verloren. Du kannst
nicht mehr darauf zugreifen, und Du kannst ihn auch nicht mehr
freigeben.
hmmm... ok, dann nur einen Pointer in der Funktion erzeugen, auf den
übergebenen Speicherbereich zeigen lassen, damit arbeiten und am Ende
der Funktion vergessen, hat mir schonmal sehr geholfen, Danke!
Habe noch eine weitere Frage, und zwar ein ähnlich gelagertes Problem,
genutzt wird die Funktion realloc.
1
BufPtr=realloc(BufPtr,LENGTH);
hier erhalte ich Errormeldung: memleakOnRealloc,
Der Speicher kann und soll allerdings tatsächlich wachsen und auch
schrumpfen können und die Errormeldung betrifft genau diejenigen Zeilen,
die im Falle des Schrumpfens aufgerufen werden.
Bin mir daher nicht sicher, ob es wirklich ein Fehler ist, oder nur eine
zu scharf eingestellte Warnung, die einen Error erzeugt, aber auch für
diesen Fall würde ich dennoch gerne wissen, wie ich "Errorfrei" aus der
Situation herauskomme...
Arduino F. schrieb:>> free(RecPointer)> Diese lokale Variable musst/darfst/kannst du nicht freigeben!> Das passiert automatisch.
Unsinn. Jeder Pointer muss man freigeben. Zu jedem malloc gehört ein
free.
Memleak schrieb:> Bin mir daher nicht sicher, ob es wirklich ein Fehler ist
Ist es, denn wenn das Realloc scheitert, kriegst Du zwar einen
Nullpointer zurück, aber damit überschreibst Du den alten Bufferzeiger,
und wie willst Du den Buffer dann jemals wieder freigeben?
Daher macht man das besser nach dem Muster:
1
BUF_T *TmpBufPtr = realloc(BufPtr, LENGTH);
2
if (TmpBufPtr == NULL)
3
{
4
// error handling
5
// BufPtr STILL points to allocated memory but can be free'd
Peter II schrieb:> Arduino F. schrieb:>>> free(RecPointer)>> Diese lokale Variable musst/darfst/kannst du nicht freigeben!>> Das passiert automatisch.>> Unsinn. Jeder Pointer muss man freigeben. Zu jedem malloc gehört ein> free.
Und warum kommt dann beim TO der Fehler?
Was hat er falsch gemacht und wie kann er es besser machen?
Adele schrieb:> Und warum kommt dann beim TO der Fehler?> Was hat er falsch gemacht und wie kann er es besser machen?
er überschreibt seinen Pointer, damit gibt er beim free den falschen
Speicher frei.
Nop schrieb:> Ist es, denn wenn das Realloc scheitert, kriegst Du zwar einen> Nullpointer zurück, aber damit überschreibst Du den alten Bufferzeiger,
Ja.
Peter II schrieb:> er überschreibt seinen Pointer, damit gibt er beim free den falschen> Speicher frei.[...]
Das liest sich so, als ob ich nach einem p1 = malloc(l1) und
anschließendem erfolgreichen p2 = realloc(p1, l2) später auch noch p1
freigeben müsste. Dem ist nicht so. Ich muss nur den zuletzt erhaltenen
Pointer freigeben, also p2.
Frank M. schrieb:> Das liest sich so, als ob ich nach einem p1 = malloc(l1) und> anschließendem erfolgreichen p2 = realloc(p1, l2) später auch noch p1> freigeben müsste. Dem ist nicht so. Ich muss nur den zuletzt erhaltenen> Pointer freigeben, also p2.
ich habe mich auf den 1. Code bezogen, da gab es kein realloc.
Memleak schrieb:> BufPtr = realloc(BufPtr, LENGTH);
Du solltest niemals das Ergebnis von realloc direkt an den übergebenen
Pointer zuweisen.
Wie signalisiert realloc, daß es keinen freien Speicher mehr gibt?
Indem es NULL zurückgibt.
Was passiert dann mit dem Pointer, der auf den bislang verwendeten
Speicher zeigt?
Er wird mit NULL überschrieben.
Und ... wie kommt man jetzt an den bislang verwendeten Speicher 'ran, um
ihn z.B. freizugeben?
Gar nicht mehr. Game Over.
Also: Das Ergebnis von realloc immer einem Hilfspointer zuweisen, den
Zielpointer erst dann überschreiben, wenn das Ergebnis nicht NULL ist.