Gdzie w pamięci są moje zmienne przechowywane w C?

Biorąc pod uwagę, że pamięć jest podzielona na cztery segmenty: dane, sterta, stos i Kod, gdzie zmienne globalne, zmienne statyczne, Stałe typy danych, zmienne lokalne (zdefiniowane i zadeklarowane w funkcjach), zmienne (w funkcji głównej), wskaźniki i dynamicznie przydzielana przestrzeń (za pomocą malloc i calloc) są przechowywane w pamięci?

Myślę, że zostaną one przydzielone w następujący sposób:

  • zmienne globalne - - - - - - - > dane
  • zmienne statyczne - - - - - - - > DANE
  • Stałe typy danych - - - - - > kod
  • zmienne lokalne (zadeklarowane i zdefiniowane w funkcjach) --------> stack
  • zmienne zadeklarowane i zdefiniowane w funkcji main - - - - - > heap
  • Wskaźniki (na przykład, char *arr, int *arr) -------> heap
  • dynamicznie przydzielana przestrzeń (za pomocą malloc i calloc) --------> stack

Mówię o tych zmiennych tylko z perspektywy C.

Proszę mnie poprawić, jeśli się mylę, ponieważ jestem nowy w C.

Author: Steve Summit, 2013-01-29

7 answers

Część z nich masz rację, ale ktokolwiek napisał pytania, oszukał cię na przynajmniej jednym pytaniu: {]}

  • zmienne globalne - - - - - - - > dane (poprawne)
  • zmienne statyczne - - - - - - - > dane (poprawne)
  • Stałe typy danych - - - - - > kod i / lub dane. Rozważmy literały łańcuchowe dla sytuacji, gdy stała sama w sobie byłaby przechowywana w segmencie danych, a odniesienia do niej byłyby osadzone w kodzie
  • zmienne lokalne (zadeklarowane i zdefiniowane w funkcjach) -------- >stack (poprawny)
  • zmienne zadeklarowane i zdefiniowane w funkcji main -----> heap również stack (nauczyciel próbował cię oszukać)
  • pointers (ex: char *arr, int *arr) -------> sterta danych lub stos, w zależności od kontekstu. C pozwala zadeklarować wskaźnik globalny lub static, w którym to przypadku wskaźnik sam w sobie skończy w segmencie danych.
  • dynamicznie przydzielana przestrzeń (za pomocą malloc, calloc, realloc) --------> stack heap

Warto wspomnieć, że "stack" jest oficjalnie nazywany "automatic storage class".

 153
Author: dasblinkenlight,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-29 17:39:05

Dla tych przyszłych odwiedzających, którzy mogą być zainteresowani wiedzą o tych segmentach pamięci, piszę ważne punkty o segmentach pamięci 5 W C:

Niektóre głowy do góry:

  1. za każdym razem, gdy program C jest wykonywany, część pamięci jest przydzielana w pamięci RAM do wykonania programu. Pamięć ta służy do przechowywania często wykonywanego kodu( dane binarne), zmiennych programu, itp. Poniższe segmenty pamięci mówią o tym samym:
  2. zazwyczaj są trzy rodzaje zmiennych:
    • zmienne lokalne (nazywane również zmiennymi automatycznymi w C)
    • zmienne globalne
    • zmienne statyczne
    • możesz mieć globalne statyczne lub lokalne zmienne statyczne, ale powyższe trzy są typami nadrzędnymi.

5 segmenty pamięci w C:

1. Segment Kodu

  • segment kodu, zwany także segmentem tekstowym, jest obszarem pamięci, który zawiera często wykonywane kod.
  • segment kodu jest często tylko do odczytu, aby uniknąć ryzyka nadpisania przez błędy programowania, takie jak przepełnienie bufora itp.
  • segment kodu nie zawiera zmiennych programu, takich jak zmienna lokalna (wywoływana również jako zmienne automatyczne W C ), zmienne globalne itp.
  • w oparciu o implementację C, segment kodu może również zawierać literały ciągu tylko do odczytu. Na przykład, gdy wykonasz printf("Hello, world"), w kodzie/tekście zostanie utworzony ciąg znaków "Hello, world" segment. Możesz to sprawdzić używając polecenia size w systemie Linux.
  • Czytaj dalej

Segment Danych

Segment danych jest podzielony na dwie poniższe części i zazwyczaj leży poniżej obszaru sterty lub w niektórych implementacjach powyżej stosu, ale segment danych nigdy nie leży między obszarem sterty i stosu.

2. Niezainicjalizowany segment danych

  • ten segment jest również znany jako bss.
  • to jest porcja pamięci który zawiera:
    1. Niezainicjalizowane zmienne globalne (W Tym zmienne wskaźnika)
    2. niezaliczone stałe zmienne globalne .
    3. Niezainicjalizowane lokalne zmienne statyczne .
  • każda globalna lub statyczna zmienna lokalna, która nie jest zainicjalizowana, będzie przechowywana w niezainicjalizowanym segmencie danych
  • na przykład: zmienna globalna int globalVar; lub statyczna zmienna lokalna static int localStatic; będą przechowywane w niezainicjowany segment danych.
  • jeśli zadeklarujesz zmienną globalną i zainicjalizujesz ją jako 0 lub NULL, to nadal trafi ona do niezainicjalizowanego segmentu danych lub bss.
  • Czytaj dalej

3. Initialized data segment

  • ten segment przechowuje:
    1. inicjalizowane zmienne globalne (W Tym zmienne wskaźnika)
    2. zainicjalizowana stała globalna zmienne .
    3. zainicjalizowane lokalne zmienne statyczne .
  • na przykład: zmienna globalna int globalVar = 1; lub statyczna zmienna lokalna static int localStatic = 1; będą przechowywane w zainicjalizowanym segmencie danych.
  • ten segment może być dalej klasyfikowany do zainicjalizowanego obszaru tylko do odczytu i zainicjalizowanego obszaru do odczytu i zapisu . zainicjalizowane stałe zmienne globalne wejdą do zainicjowanego obszaru tylko do odczytu, podczas gdy zmienne, których wartości można modyfikować w trybie runtime, wejdą do obszaru tylko do odczytu. inicjalizacja obszaru odczytu i zapisu .
  • Rozmiar tego segmentu zależy od wielkości wartości w kodzie źródłowym programu i nie zmienia się w czasie wykonywania.
  • Czytaj dalej

4. Segment Stosu

  • segment stosu służy do przechowywania zmiennych, które są tworzone wewnątrz funkcji ( funkcja może być funkcją główną lub funkcją zdefiniowaną przez użytkownika ), zmienna jak
    1. Local zmienne funkcji (W Tym zmienne wskaźnika)
    2. argumenty przekazywane do funkcji
    3. adres zwrotny
  • zmienne przechowywane w stosie zostaną usunięte po zakończeniu wykonywania funkcji.
  • Czytaj dalej

5. Segment Sterty

  • ten segment ma wspierać dynamiczną alokację pamięci. Jeśli programista chce przydzielić trochę pamięci dynamicznie, a następnie w C odbywa się to za pomocą malloc, calloc, lub realloc metody.
  • na przykład, gdy int* prt = malloc(sizeof(int) * 2) w stercie zostanie przydzielonych osiem bajtów, a adres pamięci tej lokalizacji zostanie zwrócony i zapisany w zmiennej ptr. Zmienna ptr będzie znajdować się na stosie lub segmencie danych w zależności od sposobu deklarowania/użycia.
  • Czytaj dalej
 84
Author: hagrawal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-16 08:45:36

Poprawiłem Twoje błędne zdania

constant data types ----->  code //wrong

Zmienne stałe lokalne - - - - - > stack

Zainicjalizowana stała globalna zmienna - - - - - > segment danych

Niezinicjalizowana stała globalna zmienna - - - - - > bss

variables declared and defined in main function  ----->  heap //wrong

Zmienne zadeklarowane i zdefiniowane w funkcji main - - - - - > stack

pointers(ex:char *arr,int *arr) ------->  heap //wrong

dynamically allocated space(using malloc,calloc) --------> stack //wrong

Pointers (np. char *arr,int *arr) -------> rozmiar zmiennej pointer będzie w stosie.

Weź pod uwagę, że przydzielasz pamięć n bajtów (używając malloc lub calloc) dynamicznie, a następnie czyniąc zmienną wskaźnikową do jej Wskazywania. Teraz, gdy n bajty pamięci znajdują się w stercie, a zmienna wskaźnika zawiera 4 bajty (jeśli 64-bitowa maszyna ma 8 bajtów), które będą przechowywane w stosie do przechowywania wskaźnika początkowego n bajtów pamięci.

Uwaga: zmienne wskaźnika mogą wskazywać pamięć dowolnego segmentu.

int x = 10;
void func()
{
int a = 0;
int *p = &a: //Now its pointing the memory of stack
int *p2 = &x; //Now its pointing the memory of data segment
chat *name = "ashok" //Now its pointing the constant string literal 
                     //which is actually present in text segment.
char *name2 = malloc(10); //Now its pointing memory in heap
...
}

Dynamicznie przydzielana przestrzeń (za pomocą malloc,calloc) --------> heap

 8
Author: rashok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-29 17:53:57

Popularna Architektura pulpitu dzieli pamięć wirtualną procesu na kilka segmentów :

  • Segment tekstowy: zawiera kod wykonywalny. Wskaźnik instrukcji przyjmuje wartości z tego zakresu.

  • Segment danych: zawiera zmienne globalne(tzn. obiekty ze statycznym połączeniem). Dzieli się na dane tylko do odczytu (takie jak stałe łańcuchowe) i dane niezainicjalizowane ("BSS").

  • Segment stosu: zawiera dynamiczną Pamięć dla programu, tj. wolny store ("sterta") i lokalne ramki stosu dla wszystkich wątków. Tradycyjnie stos C i sterta C rosły do segmentu stosu z przeciwnych końców, ale uważam, że praktyka została porzucona, ponieważ jest zbyt niebezpieczna.

Program C zazwyczaj umieszcza obiekty o statycznym czasie przechowywania w segmencie danych, dynamicznie przydzielane obiekty w wolnym magazynie i automatyczne obiekty na stosie wywołań wątku, w którym żyje.

W innych platformy, takie jak stary tryb rzeczywisty x86 lub urządzenia wbudowane, rzeczy mogą być oczywiście radykalnie różne.

 6
Author: Kerrek SB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-29 17:42:31

odnoszę się do tych zmiennych tylko z perspektywy C.

Z punktu widzenia języka C liczy się tylko Zakres, Zakres, powiązanie i dostęp; dokładnie to, jak elementy są mapowane do różnych segmentów pamięci, zależy od indywidualnej implementacji, a to będzie się różnić. Standard języka w ogóle nie mówi o segmentach pamięci . Większość nowoczesnych architektur działa głównie w ten sam sposób; zmienne blokowe i funkcja argumenty zostaną przydzielone ze stosu, zakres plików i zmienne statyczne zostaną przydzielone z segmentu danych lub kodu, pamięć dynamiczna zostanie przydzielona ze sterty, niektóre stałe dane będą przechowywane w segmentach tylko do odczytu, itd.

 5
Author: John Bode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-29 17:58:06

Pointers (ex:char *arr,int *arr) -------> heap

Nie, mogą być na stosie lub w segmencie danych. Mogą wskazywać wszędzie.

 1
Author: Steve Wellens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-29 17:38:07
  • zmienne / zmienne automatyczne - - - > sekcja stosu
  • dynamicznie przydzielane zmienne - - - > sekcja sterty
  • inicjalizowane zmienne globalne - > sekcja danych
  • Niezainicjalizowane zmienne globalne - > sekcja danych (bss)
  • zmienne statyczne - > sekcja danych
  • stałe łańcuchowe - > sekcja tekstowa / sekcja kodu
  • Funkcje - > sekcja tekstowa / sekcja kodu
  • Kod tekstu - >sekcja tekstowa / sekcja kodu
  • rejestry - > rejestry procesora
  • command line inputs - > environmental/command line section
  • zmienne środowiskowe - > sekcja środowiskowa/wiersz poleceń
 1
Author: prashad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-16 08:40:25