2012-10-13 9 views
15

Gwarantuję, że pytanie to zostało zadane wcześniej, ale nie udało mi się go znaleźć za pomocą wyszukiwarki; przepraszam z góry za wszelkie zwolnienia.C Tworzenie aranżacji - stos lub rozmieszczenie sterty?

To moje (potencjalnie błędne) zrozumienie, które można przydzielić tylko do stosu, gdy znany jest rozmiar obiektu podczas kompilacji. Tak więc w przypadku inicjalizacji tablicy, można wykonać jedną z nich (i to powinno iść na stosie):

char charArray[50]; 

Ponieważ rozmiar tej tablicy jest znany w czasie kompilacji, to nie powinien mieć problemów.

Z drugiej strony, to (wierzę) to także ważny kod:

char anotherCharArray[someVariable + 50]; 

byłoby to na stosie, jak również? Jestem prawie pewny, że kod ulega uszkodzeniu, jeśli zwolnisz() to, więc to sprawia, że ​​myślę, że tak, ale to naprawdę nie ma dla mnie sensu. Podobnie jest w 100% wyłącznej sytuacji, w której trzeba użyć free(), gdy dane zostały przydzielone za pośrednictwem malloc?

Z góry dziękuję za pomoc.

+2

@Shookit: musisz określić, czy mówisz o zmiennych lokalnych lub globalnych. –

+0

@PaulR, jeśli tablica ma zmienną długość, nie może znajdować się w zasięgu globalnym. –

+1

Musisz odróżnić * automatyczną pamięć masową * i * stos *, która jest niskopoziomowym sposobem przechowywania danych. Dane umieszczone w pamięci automatycznej można umieszczać również w innych miejscach, np. W rejestrach. W przypadku lokalnej tablicy o nieznanym rozmiarze (znanej jako VLA: s), kompilator może umieścić ją na stosie, można także przydzielić pamięć na stercie (tak długo, aż zwolni ją w odpowiednich miejscach). W rzeczywistości, VLA: s nie idą dobrze razem z 'setjmp' /' longjmp', ponieważ mogą przeciekać (i są dopuszczone do tego przez standard C). – Lindydancer

Odpowiedz

4

Podobnie jest w 100% wyłącznej sytuacji, w której trzeba użyć free(), gdy dane zostały przydzielone za pośrednictwem malloc?

Tak. (Oprócz calloc i realloc, ich wartość zwracana ma być również free() 'd. Podobnie, istnieją funkcje, które używają malloc() i fakt ten jest udokumentowany, na przykład strdup() - zwracana wartość tych funkcji jest również zwalniana przy użyciu free(), oczywiście.)

char anotherCharArray[someVariable + 50]; 

byłoby to na stosie, jak również?

Tak, to robi (w większości implementacji - oczywiście nie zawsze prawda, że ​​można zakładać, ale na większości platform, to jest). I tak, to jest poprawny kod, ale jest tylko standardowy w C99.

+0

W porządku, więc wydaje mi się, że moim największym błędem było założenie, że przydział pamięci stosu wymaga znajomości rozmiaru podczas kompilacji? Oznaczyłem to jako odpowiedź (ale wciąż mogę odpowiedzieć na mój komentarz :) – Shookit

+6

@Shookit Tak, to kompletne nieporozumienie; posiadanie znanego rozmiaru jest nieistotne dla miejsca, w którym coś zostało przydzielone. Jedynym połączeniem jest to, że w poprzednich wersjach C, z różnych przyczyn historycznych, zmienne 'auto' musiały mieć znany rozmiar, a tylko zmienne" auto "mogą być przydzielane na stosie. –

+0

@JimBalter odpowiedział na twoje pytanie bardzo dobrze :) –

7

Jeśli zdefiniowano char charArray[50]; w zasięgu pliku (poza wszystkimi funkcjami) lub static, to nie będzie na stosie, będzie to globalna prealokacja przy zmiennej startowej programu. Jeśli nie jest to static i jest zdefiniowany w zakresie funkcji, będzie na stosie.

może być zdefiniowany tylko w zakresie funkcji i będzie znajdował się na stosie.

Wszystkie powyższe zasady odnoszą się do typowych implementacji C. Nietypowe mogą wykorzystywać stertę zamiast stosu i zamiast wstępnie przydzielonego miejsca w sekcji danych programu.

Nie musisz free(), co nie zostało przydzielone z malloc(), calloc() lub realloc(). Prosty. Niektóre funkcje mogą oznaczać użycie jednego z powyższych, np. POSIX strdup().

+1

Jeśli jesteśmy w zasięgu globalnym, 'char someArray [variableLenght]; 'is not allowed ... –

+0

@ H2CO3 Czy ostatnia edycja usunęła niejednoznaczność? Nie widzę, w którym miejscu sugerowałbym, że jest to dozwolone w skali globalnej. –

Powiązane problemy