Sida 1 av 1

C-fråga angående pekare

Postat: 19 januari 2011, 12:26:07
av ie
Vad händer om man gör "free" på en pekare som pekar på en konstant?

Ex.

Kod: Markera allt

f(char *p)
{
     free(p);
}

1:
char *s = malloc(20);
f(s);

2:
f("Test");
Ex 1 är ok men vad händer i fall 2?

Tanken bakom frågan är att man vill kunna anropa en funktion på olika sätt och i detta fall vill jag att allokerat minnesutrymme ska tas bort. Visst kan jag göra det efter anropet till f() men för att spara en kodrad på många ställen vore det bra om det kunde ske i funktionen.

Går det att lista ut vilken "typ" av pekare funktionen får?

Jag antar att man måste bita i det sura äpplet och bestämma sig för att hantera det ena ELLER andra sättet, att det inte går att kombinera.

Re: C-fråga angående pekare

Postat: 19 januari 2011, 12:34:30
av jesse
Nu är inte jag någon expert på "C", men om man skriver ("text") som argument så skapas väl en text i ramminnet som i praktiken fungerar som vilken vektor som helst, bara det att det inte finns någon symbol (variabelnamn) som pekar på den. Pekaren skickas dock som argument till funktionen och eftersom texten inte används mer kan utrymmet frigöras?

bara mina spekulationer.

Re: C-fråga angående pekare

Postat: 19 januari 2011, 14:09:49
av SvenW
>> Går det att lista ut vilken "typ" av pekare funktionen får?

Nej. I funktionen är den deklarerad char * och då är den det.
Var den är allokerad vet man inte.

>> Jag antar att man måste bita i det sura äpplet och bestämma sig för att
hantera det ena ELLER andra sättet, att det inte går att kombinera.

Ja.

>> Vad händer om man gör "free" på en pekare som pekar på en konstant?

Under ett operativsystem blir det sannolikt segfault.
I en naken enchipsprocessor är det oklart vad som händer.
(Om funktionen free() överhuvudtaget finns í en nakenmiljö)

Inom C och C++ måste man vara pedantiskt noga med malloc() och free().
Det är kanske dessa språks största svagheter.

Re: C-fråga angående pekare

Postat: 19 januari 2011, 14:26:32
av danwi
Ett stort tips för att undvika problem med såna konstruktioner är att köra splint eller liknande verktyg för statisk kodanalys. Du får garanterat smäll på fingrarna om du försöker göra free() på en pekare till en konstant :)

Re: C-fråga angående pekare

Postat: 19 januari 2011, 14:56:42
av pbgp
Jag vet inte om jag tillför något, men i Linux Programmers Manual står:

free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc().

Alltså, free() får bara anropas med pekare som returnerats av malloc, calloc eller realloc som argument. Anledningen är att dom rutinerna håller reda på en datastruktur för minne allokerat från den så kallade heapen. En konstant har inte allokerats på heapen och du riskerar att förstöra mallocs datastruktur och få en segfault (eller annan läskighet) långt senare. Beteendet är odefinierat :)

Detta är som sagt på linux med någon version av libc, i din miljö kanske det funkar annorlunda.

Re: C-fråga angående pekare

Postat: 19 januari 2011, 17:54:19
av Icecap
Free får inte köras utan att minnet är allokerat med en lämplig allokeringskall. Det är i µC-sammanhang synnerligt dumt att använda denna teknik om man har en µC med begränsade resurser då implementeringen av malloc/free kostar mer än man kan spara.

Men vill man använda samma minnesområde till fler saker är union kanske vägen att gå.

Kommer man upp i µC med lite musklar och en del minne kan det dock vara aktuellt med att allokera minne men i PIC18-storlek är det bara spill.

Re: C-fråga angående pekare

Postat: 19 januari 2011, 18:11:07
av nablaman
Din sträng "Text" kommer placeras i den körbara filens datasegment, dvs lagras på samma sätt som programkoden. Så en pekare av typen
char *x = "Text";
kommer enkelt uttryckt peka på en plats i minnet där den körbara filen laddats in. Att trixa med denna pekare är därför förenat med livsfara :)
(de flesta moderna OS kommer dock mappa denna del av datasegmentet read-only så det som kommer hända är att OS:et säger ifrån att du försöker skriva till
en adress som bara får läsas, och då får man ett segmentation fault eller motsvarande).
Det är länkaren som är ansvarig för att samla ihop objektkod, statisk data, etc till en körbar fil, som sedan mappas in i minnet när programmet laddas.
(Ovan gäller åtminstone på "normala datorer". Embedded-världen kan jag inte uttala mig om.)

Mer info: http://en.wikipedia.org/wiki/Data_segment

Re: C-fråga angående pekare

Postat: 20 januari 2011, 03:21:13
av jesse
Det beror nog på vilken processor man kompilerar för. Det kan hända att det funkar så för en PC där den körbara koden finns i RAM, men det skulle inte fungera i en AVR som har programmet i FLASH som kräver speciella instruktioner för att läsa data. Ändå går det att göra så funktion("text"); även i AVR eftersom kompilatorn då låter programmet lägga texten i RAM och skickar pekaren, tror jag.

Re: C-fråga angående pekare

Postat: 20 januari 2011, 18:25:20
av ie
Tack för alla svar. Det var alltså som jag anade.

Tycker dock att allokerat minne är användbart i en Mega88 (och dess storasyskon), Ser inte att union är ett alternativ. I vissa specifika fall kanske...

I det aktuella fallet allokerar jag minne till ett meddelande som jag lägger i en kö. Sen hämtar en annan "modul" meddelandet och återlämnar minnet.

Re: C-fråga angående pekare

Postat: 21 januari 2011, 08:04:57
av Nerre
Problemet är att informationen om vad som är allokerat tar upp plats också. Så det går åt mer minne om du ska hålla på och allokera.

Re: C-fråga angående pekare

Postat: 21 januari 2011, 20:42:29
av kimmen
ie skrev:Vad händer om man gör "free" på en pekare som pekar på en konstant?
Det går nog under "Undefined behavior" (se t.ex. http://en.wikipedia.org/wiki/Undefined_behavior), dvs. ungefär vad som helst kan hända. Troligtvis kraschar programmet eller uppför sig fel, antingen direkt eller när som helst senare... :mrgreen: