Bästa svaret
Jag antar att du vet att när du kör ett C-program har du 3 öppna filer, två av dem heter STDOUT och STDERR, vanliga meddelanden går in i stdout, (dvs när du ringer till printf) och felmeddelanden till stderr (när du ringer till exempel fprintf (stderr, …), är dessa två (öppna filer faktiskt) direkt länkade av ditt operativsystem till din terminal, vara en Unix-terminal eller en Windows-terminal. Det viktigaste med dem är att de kan omdirigeras, till exempel i Unix när du gör det: ls | grep file.txt shell omdirigera stdout i ”ls” och nu destinationen för den utgången är STDIN i ”grep” -processen, så grep kan leta efter mönster i den strömmen osv. Detta är kraftfulla saker, många Unix-filter (program faktiskt) är byggda på detta sätt, vilket är kraftfullt.
EDIT: lägg till ett mer meningsfullt exempel Låt mig lägga till en ny och mer uttrycklig användning av omdirigering så att du kan förstå saken med ett mer betydelsefullt exempel, titta på det här kommandot:
curl http://ftp.gnu.org/gnu/wget/wget-1.17.1.tar.xz | xzcat – | tar xvf –
Här börjar curl att ladda ner wget från GNU-projektet, medan curl laddar ner data som det skriver till STDOUT, men skalet har omdirigerat stdout av curl till stdin av xzat, skalet gör samma, omdirigerar stdout av xzcat till stdin av tjära, och tar börjar att komprimera data, fantastiskt!
Svar
Först en allmän princip: oavsett vad du gör, malloc()
åberopas aldrig automatiskt.
När du deklarerar en struct
förklarar du en typ. En typ, i sig själv, förbrukar inget minne vid körning.
När du deklarerar en variabel av strukturtyp tilldelas minnet för den, men använder inte malloc()
. Om variabeln är lokal till en funktion tilldelas vanligtvis minne för den på stacken. Detta är delvis det som möjliggör rekursivitet i C: varje gång du ringer till funktionen (även om den anropas inifrån sig) justeras stackpekaren och nytt utrymme är reserverat på stacken för loc alla variabler för den funktionen, och varje gång funktionen avslutas, ”stackes” stacken med allt utrymme frigjort.
När du förklarar en global variabel görs en statisk allokering för den på högen när programmet startar och variabeln förblir tillgänglig under hela genomförandet av programmet. Den erforderliga högstorleken är känd vid kompileringstidpunkten.
Däremot, när du använder malloc()
, allokeras minnet dynamiskt vid körning till programmet av operativsystemet och du är ansvarig för att frigöra det med free()
, eller så kommer ditt program (särskilt om det är ett program som körs länge utan omstart, t.ex. en tjänsteapplikation) lider av en minnesläckage, vilket påverkar prestanda och i extrema fall svälter hela resurssystemet. Användningen av malloc()
är mest lämplig när antingen a) den erforderliga mängden minne är mer än vad som kan tilldelas på högen eller stacken, eller b) mängden minne som krävs inte är känd i förväg.