[C] Geheugenvraag

Pagina: 1
Acties:

  • Skinkie
  • Registratie: Juni 2001
  • Laatst online: 09-06-2020

Skinkie

Op naar de 500

Topicstarter
code:
1
2
3
4
5
6
7
int main(int argc, char *argv) {
    char **string;
    int bla;
    bla=0;
    input(string);
    free(*string);
}


waarom werkt het volgende stukje code alleen in de bovenstaande volgorde en niet in de volgende volgorde, die overigens resulteert in een segfault.

code:
1
2
3
4
5
6
7
int main(int argc, char *argv) {
    int bla;
    char **string;
    bla=0;
    input(string);
    free(*string);
}

Steun Elkaar, Kopieer Nederlands Waar!


  • ^Mo^
  • Registratie: Januari 2001
  • Laatst online: 04-11-2025
Gaat wat fout met alloceren in de functie input(); post daar eens de code van.

"There are 10 kinds of people in the world, those who understand binary and those who don't" | Werkbak specs


  • Skinkie
  • Registratie: Juni 2001
  • Laatst online: 09-06-2020

Skinkie

Op naar de 500

Topicstarter
code:
1
2
3
int input(char **string) {
    (char *)*string=(char *)malloc(255*sizeof(char));
}

alleen dit stukje code zorgt al voor de schade...

Steun Elkaar, Kopieer Nederlands Waar!


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:19
Ja en waar dacht je dat 'string' naar verwees? Probably nergens, dus iets aan '*string' toekennen gaat niet goed. Je hebt mazzel dat 't op de andere manier stomtoevallig wel werkt.

Ik denk dat je eigenlijk zo iets bedoelde:
.
C:
1
2
3
4
5
6
7
int main(int argc, char *argv) {
    int bla;
    char *string;
    bla=0;
    input(&string);
    free(string);
}

.
In dit soort gevallen ben ik trouwens meer voor een return value dan een argument dat aangepast wordt, dat scheelt een hoop gedoe met dubbele pointers (wat snel voor fouten zorgt, omdat het lastig te overzien is).

edit:
Oh; en of je dan eerst 'bla' en dan 'string' declareert of andersom, maakt dan niet meer uit natuurlijk.

[ Voor 18% gewijzigd door Soultaker op 21-11-2002 22:38 . Reden: Stomme kutforum snapt geen newlines ]


  • Skinkie
  • Registratie: Juni 2001
  • Laatst online: 09-06-2020

Skinkie

Op naar de 500

Topicstarter
Okee, ik begrijp nu dat de pointer **string nergens naar verwijst, en waarschijnlijk begrijp ik nu ook waarom die int volgorde uitmaakte... echter zou ik een dubbele pointer kunnen gebruiken als ik deze eerst zou mallocen?

Dit werkt... maar is het ook correct c?
code:
1
2
3
4
5
6
7
8
9
int main(int argc, char *argv) {
    char **string;
    int bla;
    bla=0;
    (char **)string=(char **)malloc(sizeof(char *));
    input(string);
    free(*string);
    free(string);
}

[ Voor 39% gewijzigd door Skinkie op 21-11-2002 22:49 . Reden: code toegevoegd ]

Steun Elkaar, Kopieer Nederlands Waar!


  • Thijsch
  • Registratie: Februari 2002
  • Laatst online: 22-08 19:17
code:
1
2
3
4
5
6
7
int main(int argc, char *argv[])
{
 char *string;
 int bla = 0;
 string = (char *)malloc(sizeof(char *));
 free(string);
}


of

code:
1
2
3
4
5
6
int main(int argc, char *argv[])
{
 char *string = (char *)malloc(sizeof(char *));
 int bla = 0;
 free(string);
}

die input(string); doet dan toch niets meer?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:19
Skinkie schreef op 21 November 2002 @ 22:42:
Dit werkt... maar is het ook correct c?
Ja hoor, dat is helemaal correct. Maar als je die waarde toch alleen maar daar nodig hebt, kun je 'm net zo goed op de stack alloceren natuurlijk. Heap allocation is vergeleken daarmee vrij duur.

ParaDot: ik neem aan dat het uiteindelijk de bedoeling is dat input() veel meer gaat doen en dan is het natuurlijk praktisch om die code in een aparte functie te hebben staan.

Je hoeft trouwens het resultaat van de assignment (of de variabele zelf; ik weet niet precies wat voorrang heeft) niet nog eens te gaan casten. Zo is 't meer dan genoeg:
C:
1
2
3
4
/* Niet zo: */
(char **)string=(char **)malloc(sizeof(char *));
/* Maar zo: */
string=(char **)malloc(sizeof(char *));

In principe zijn casts natuurlijk een beetje verdacht, dus als je ze overbodig zijn, kun je ze beter vermijden.

[ Voor 30% gewijzigd door Soultaker op 22-11-2002 00:53 ]


  • Skinkie
  • Registratie: Juni 2001
  • Laatst online: 09-06-2020

Skinkie

Op naar de 500

Topicstarter
Soultaker schreef op 22 November 2002 @ 00:51:
Maar als je die waarde toch alleen maar daar nodig hebt, kun je 'm net zo goed op de stack alloceren natuurlijk. Heap allocation is vergeleken daarmee vrij duur.
Zoals je uit mijn vraag wel kunt begrijpen ben ik een newbie op geheugen beheer, omdat stack en heap allocation me niets zeiden heb ik maar even gezocht. Maar hoe kan ik een stack allocation maken??? (just for the question)
Overigens wordt die variabele veel verder in het systeem doorgegeven... het moet zelfs door een linked list heen... (de linked list heb ik overigens zelf in ansi-c gecode... ik denk dat de meeste mensen hun hart zullen vasthouden :))

Steun Elkaar, Kopieer Nederlands Waar!


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Soultaker: Je hoeft trouwens het resultaat van de assignment (of de variabele zelf; ik weet niet precies wat voorrang heeft) niet nog eens te gaan casten.
In alle talen in de categorie C/C++/C#/Java heeft assignment (soms vrijwel) de laagste prioriteit. De prioriteit van de cast ligt net boven die van de expressies met binaire operatoren, maar net beneden de expressies met unaire operatoren en postfix expressies. Daarom kan je een subscript van een array ook casten zonder haakjes te zetten om de hele subscript expressie, maar slaat een cast in zo'n expressie: (T) e1 + e2 alleen op de e1.

In dit geval wordt de lvalue van de assignment dus gecast:
C:
1
((char **) string) = (char **) malloc(sizeof(char *));

In alle gevallen is het natuurlijk even onzinnig ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:19
Skinkie schreef op 22 November 2002 @ 01:04:
Zoals je uit mijn vraag wel kunt begrijpen ben ik een newbie op geheugen beheer, omdat stack en heap allocation me niets zeiden heb ik maar even gezocht. Maar hoe kan ik een stack allocation maken??? (just for the question)
Alle lokale variabelen worden op de stack gealloceerd. Mijn (eerste) voorbeeld demonstreert hoe je je pointervariabele op de stack kunt alloceren door m'n simpelweg lokaal te declareren en vervolgens er een pointer naar te 'maken' met de &-operator.

Uiteraard worden op de stack gealloceerde variabelen opgeruimd wanneer ze uit hun scope verdwijnen (in dit geval, als main() wordt afgesloten). Je kunt het dus niet gebruiken om waarden terug te geven (zoals je met input() wilt doen); in dat geval zul je het geheugen echt op de heap moeten alloceren. Als pointer-waarden opgeruimd worden, wordt het geheugen waar ze naar verwijzen trouwens niet opgeruimd, dus je hebt hoe dan ook een call naar free() nodig om het geheugen op te ruimen.

Aangezien geheugen op de heap alloceren relatief lang duurt, voor memory fragmentation zorgt (terwijl de stack daar geen last van heeft) en pointers naar de heap relatief minder vaak in de cache te vinden zijn, is het vrijwel nooit zinnig om geheugen dat alleen binnen de scope van een bepaalde functie bestaat, met malloc() op de heap te alloceren (zoals je in je tweede voorbeeld deed). Dat is zowel minder efficient (om de redenen die ik noemde) als moeilijker: het kost meer code en er bestaat een kans dat je geheugen vergeet te dealloceren.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:19
mbravenboer schreef op 22 november 2002 @ 01:16:
In alle talen in de categorie C/C++/C#/Java heeft assignment (soms vrijwel) de laagste prioriteit.
Als jij het zegt. ;) Het maakt mij nooit zoveel uit.

* Soultaker O+ haakjes.
Pagina: 1