[C] realloc() på en pekare sänd som funktionsargument

Permalänk
Medlem

[C] realloc() på en pekare sänd som funktionsargument

Det var länge sedan jag kodade annat än webbapplikationer, så nu är jag lite ihoptrasslad i minnesallokeringsträsket...

Följande exempelkod borde illustrera mitt problem och egentliga fråga:

funktion(char *str) { /* en massa saker och dels då en dynamiskt växande intern sträng med all debugging output från den här funktionen som jag skulle vilja kopiera över till strängen som anges som argument */ // copy our final output into given string char *tmp = realloc(str, 1024); if (tmp != NULL) { printf("realloc ok\n"); // för debugging kring mitt problem strOutput = tmp; // det är det här som inte ger utslag bortom funktionsklamrarna strcpy(str, "en massa debugging output fran funktionen som korts"); printf("%s\n", str); // ger ovanstående text precis som väntat free(tmp); } }

Och vid anrop...

char *str = NULL; funktion(str); printf("%s", str); // ger (null), således har den ompekade "str" inte haft någon verkan utanför funktionen... free(str);

Min egentliga fråga: kan jag inte peka om pekaren till annan yta (den större reallokerade) inne i funktionen och få ändringen gjord utanför, eller måste jag med funktionen returnera en pekare mot nya minnesplatsen?

En pekare är ju som vilken variabel som helst, fast med ett värde mot en annan minnesplats och vid funktionsanrop skapas väl då en lokal kopia av pekaren inom funktionen, vilket skulle kunna förklara mitt nederlag i koddesign.

Har jag rätt? Problemet kanske bara uppstår vid reallokering och i och med att jag ändrar pekaren och inte bara innehållet dit den pekar.

Anledningen till att jag vill skicka med en tom pekare och allokera upp ytan inne i funktionen är för att jag inte vet på förhand hur mycket output det kommer bli.

Visa signatur

We shall never cease from exploration And the end of all our exploring Will be to arrive where we started And know the place for the first time.
- T. S. Eliot

Permalänk
Medlem

åh helvete... jag postade i ärlighetens namn ett grymt informativt inlägg om scopes och hela baletten, men så råkade jag komma åt något kortkommando för att ändra sida i browsern och så var allt borta. Klassiker.

Iallafall, snabbversionen är: Låt funktionen returnera pekaren!

Samt gäller scoping på precis samma sätt för pekare som för variabler. Blanda däremot inte ihop värdet på pekaren (scopas) och värdet på minnesinnehållet som pekaren pekar till (scopas givetvis inte)!

Permalänk
Medlem

Tack för svaret, det var precis det jag ville ha bekräftat.

Visa signatur

We shall never cease from exploration And the end of all our exploring Will be to arrive where we started And know the place for the first time.
- T. S. Eliot

Permalänk
Medlem

void funktion(char **str) { char *tmp = realloc(*str, 1024); *str = tmp; // notera att *str är addressen till din sträng, inte str, (*str)[0] eller **str är första bokstaven, osv strcpy(*str, "hello"); // du ska inte anropa free på tmp heller, för det skulle ju betyda att du inte kan använda detta utrymme utanför funktion() } char *str = NULL; funktion(&str); // du måste skicka addressen till str, dvs en dubbelpekare. puts(str); free(str);

Permalänk
Medlem
Skrivet av dazen:

void funktion(char **str) { char *tmp = realloc(*str, 1024); *str = tmp; // notera att *str är addressen till din sträng, inte str, (*str)[0] eller **str är första bokstaven, osv strcpy(*str, "hello"); // du ska inte anropa free på tmp heller, för det skulle ju betyda att du inte kan använda detta utrymme utanför funktion() } char *str = NULL; funktion(&str); // du måste skicka addressen till str, dvs en dubbelpekare. puts(str); free(str);

Dubbelpekare, minsann. Snajsigt! Och ang. free(tmp) gav det självklart problem även när jag returnerade pekaren märkte jag, så den raden är redan åtgärdad. Tusen tack!

Visa signatur

We shall never cease from exploration And the end of all our exploring Will be to arrive where we started And know the place for the first time.
- T. S. Eliot