[C] geheugenruimte van een functie free'en

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Mr_gadget
  • Registratie: Juni 2004
  • Laatst online: 20-09 14:54

Mr_gadget

C8H10N4O2 powered

Topicstarter
Het is een beetje een basic vraag maar ik zit een beetje vast. Heb zelfs in het standaardwerk 'the C programming language' van K&R geen voorbeeld kunnen vinden hierover :/ . De functie convert_to_array wordt in de main in een for loopje meerder keren aangeroepen. Hier wordt dus telkens geheugen voor gealloceerd, dit programma werkt prima. Maar volgens mij heeft het een geheugenlek want ik geeff de ruimte nooit vrij. Echter als ik free(arr) doe krijg een Heap corruption error. Hoe zou het dan moeten?

C:
1
2
3
4
5
6
7
8
9
10
11
//main.c (rest van het programma even weg gelaten)
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "functions.h" // header file with functions
main(){
int i;
char *arr;          
arr=convert_to_array(i);
}

C:
1
2
3
4
5
6
7
8
 char* convert_to_array(int num)
  {
    char *arr;
    arr = malloc((int)log10(num)*sizeof(char));         //allocate memory
    sprintf (arr, "%d" ,num); //(num, buf, 10);
    return arr; // return pointer

  }

Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Even zonder inhoudelijk C te kennen, wanneer wil je het vrijgeven?
Want als ik je voorbeeldcode zo zie dan alloceer je wat geheugen voor je array. Zonder geheugen is die array weg, oftewel heb je wel een punt dat je klaar bent met die array?

Sowieso verwacht ik dat je een uitdaging hebt met het vrijgeven, uit mijn hogere school tijd staat me bij dat een pointer enkel een verwijzing naar het begin adres is en niets zegt over de lengte, oftewel alle kenmerken voor het gebruikte geheugen gaan out of scope, je weet enkel nog waar het begint en dat valt niet vrij te geven (please correct me if i'm wrong ;) )

Acties:
  • 0 Henk 'm!

  • naikon
  • Registratie: November 2005
  • Laatst online: 18-11-2022
Je convert_to_array() heeft een buffer overflow. Sprintf schrijft namelijk ook een NUL aan het einde van de string. Ook levert bijvoorbeeld log10(1) 0 op terwijl je toch 1 cijfer wilt printen. Tevens kan het getal negatief zijn, wat ook weer een extra character oplevert.

[ Voor 17% gewijzigd door naikon op 04-10-2010 00:46 ]


Acties:
  • 0 Henk 'm!

  • Mr_gadget
  • Registratie: Juni 2004
  • Laatst online: 20-09 14:54

Mr_gadget

C8H10N4O2 powered

Topicstarter
Na arr=convert_to_array(i); worden er nog wat bewerkingen gedaan. Daarna zou ik hem vrij willen geven aangezien convert_to_array daarna weer wordt aangeroepen. Idealiter zou ik misschien beter in de main loop malloc moeten aanroepen en het adres moeten meegeven aan de functie. Maar het zou zo ook moeten kunnen toch?

Acties:
  • 0 Henk 'm!

  • naikon
  • Registratie: November 2005
  • Laatst online: 18-11-2022
De fout zit hem niet in je free() call in de mainloop, maar het feit dat convert_to_array() in geheugen schrijft dat niet geallocate is. Vandaar je heap corruption. Deze word echter pas gedetecteerd op het moment dat free() word aangeroepen.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-09 18:51
Mr_gadget schreef op maandag 04 oktober 2010 @ 00:31:
Hier wordt dus telkens geheugen voor gealloceerd, dit programma werkt prima. Maar volgens mij heeft het een geheugenlek want ik geef de ruimte nooit vrij. Echter als ik free(arr) doe krijg een Heap corruption error. Hoe zou het dan moeten?
Dat heb je goed gezien en free(arr) is ook precies wat je moet doen om het geheugen vrij te geven. :)

Dat je een heap corruption error krijgt, komt misschien vanwege het probleem dat naikon noemde. Treedt dat ook op als je (zeg) 100 bytes alloceert (om te testen)?

Overigens kan een heap corruption wel overal hebben plaatsgevonden. Loop je code nog eens goed na op, of compileer of run met een memory debugger als valgrind of mudflap om fouten te vinden.

[ Voor 14% gewijzigd door Soultaker op 04-10-2010 00:52 ]


Acties:
  • 0 Henk 'm!

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 12:07
[quote]
Mr_gadget schreef op maandag 04 oktober 2010 @ 00:45:
Na arr=convert_to_array(i); worden er nog wat bewerkingen gedaan. Daarna zou ik hem vrij willen geven aangezien convert_to_array daarna weer wordt aangeroepen. Idealiter zou ik misschien beter in de main loop malloc moeten aanroepen en het adres moeten meegeven aan de functie. Maar het zou zo ook moeten kunnen toch?
Zo zou het ook moeten werken, maar nu moet je wel documenteren dat de functie geheugen alloceert en dat de caller zelf moet opruimen. Door die pointer mee te geven aan de functie voorkom je dat en ben je ook flexibeler: het werkt dan ook voor geheugen wat op de stack is gealloceerd.

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20-09 18:51
@Jaap-Jan: daar gaat het nu echter niet om, of wel? Sowieso weet de caller natuurlijk niet precies hoeveel geheugen gealloceerd moeten worden. Als je de caller de buffer laat alloceren kun je ook net zo goed direct sprintf() callen, want dat is alles wat die testfunctie nog doet.

Acties:
  • 0 Henk 'm!

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 12:07
Soultaker schreef op maandag 04 oktober 2010 @ 00:54:
@Jaap-Jan: daar gaat het nu echter niet om, of wel? Sowieso weet de caller natuurlijk niet precies hoeveel geheugen gealloceerd moeten worden. Als je de caller de buffer laat alloceren kun je ook net zo goed direct sprintf() callen, want dat is alles wat die testfunctie nog doet.
Op te lossen met een losse functie die dat wel weet. :P Maar verder heb je natuurlijk gelijk. :)

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett

Pagina: 1