MemleakErrormeldung

Gast #5132170
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.
1
void function(char* buf)
2
{
3

4
//... ein paar Aktionen
5

6
char* RecPointer = (char*) malloc(sizeof(char) * strlen(buf));
7
RecPointer = buf;
8

9
/*... 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?
Gast
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?
Gast
> 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.
Persönliche Seite
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.
Gast
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...
Gast
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
6
} else
7
{
8
    BufPtr = TmpBufPtr ;
9
    // more stuff
10
}
Gast
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?
Gast
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.
1
char* RecPointer = (char*) malloc(sizeof(char) * strlen(buf));

so jetzt überschreibt er den Zeiger, wo er sich Speicher besorgt hat.
1
RecPointer = buf;

damit war das malloc sinnlos. Das Free gibt dann den Speicher von buf 
was so bestimmt nicht gewollt ist.
Moderator Persönliche Seite
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.
Gast
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.
Persönliche Seite
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.