• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Czy deklaracja/definicja tablicy rezerwuje pamięć komputera?

+1 głos
119 wizyt
pytanie zadane 8 stycznia 2021 w C i C++ przez ceyej64281 Nowicjusz (130 p.)

Czy deklaracja tablicy:

int tab[10][12];

rezerwuje miejsce w pamięci komputera? Deklaracja tego nie robi, więc musiałaby być to też definicja. Każda definicja jest deklaracją, nie odwrotnie.

Czy ta deklaracja jest też definicją jak w przypadku: 

int a;

, gdzie następuje taka rezerwacja. Natomiast deklaracją, a nie definicją jest na pewno:

extern int a;

Czy tablicę da się tylko zadeklarować, czyli sprawić by program wiedział o niej, aczkolwiek nie zarezerwował jeszcze pamięci.

Szukałem troszkę, znaleźć nic nie mogę. Wydaje mi się, że:

int tab[10][12];

jednak jest definicją i miejsce w pamięci zostaje jej przypisane.

Jaka więc jest prawda? Każda tablica zadeklarowana w sposób powyżej rezerwuje miejsce w pamięci czy nie?

1 odpowiedź

+1 głos
odpowiedź 8 stycznia 2021 przez Wiciorny Ekspert (219,270 p.)

Możesz odwołać się do adresu w pamięci dla deklaracji, więc taka zmienna jest w rejestrze, ale czy musi zajmować pamięć?
Jeśli jest to zmienna prosta- nie musi, nie zajmuje wtedy stosu. Jeśli jest to obiekt, wtedy generalnie zawiera.

Nic w standardach nie nakazuje, aby istniał stos. I nic w standardzie nie nakazuje, aby zmienna lokalna potrzebowała przydzielonej pamięci. Zmienna może zostać umieszczona w rejestrze lub nawet całkowicie usunięta w ramach optymalizacji.

W jęzuku C 

3.2.1 Alokacja pamięci w programach w C.

Alokacja automatyczna ma miejsce, gdy deklarujesz zmienną automatyczną, taką jak argument funkcji lub zmienna lokalna. Miejsce na zmienną automatyczną jest przydzielane po wprowadzeniu instrukcji złożonej zawierającej deklarację i jest zwalniane po zakończeniu tej instrukcji złożonej. W GNU C rozmiar automatycznego przechowywania może być różnym wyrażeniem. W innych implementacjach C musi to być stała.

komentarz 9 stycznia 2021 przez ceyej64281 Nowicjusz (130 p.)

Konktetnie to chodzi mi o język C++. Mianowicie czy komputer zawsze rezerwuje pamięć dla tablic w momencie wykonywania kodu np.

int tab[10][12];

 

komentarz 9 stycznia 2021 przez Sadako Obywatel (1,240 p.)

Oglnie, jak Wiciorny pisał, optymalizacja w kompilatorach jest w dzisiejszych czasach niesamowicie rozwinięta więc zawsze jest trudnym ograniczeniem do udzielenia odpowiedź.

Mogę Ci powiedzieć tylko, że zazwyczaj, taka zmienna bedzie alokowana na stosie. Chce też rozwiać wątpliwośći odnośnie "w momencie wykonywania kodu". Tutaj warto też postawić sobie pytanie "kiedy?". Bo pamięć na stosie jest alokowana inaczej niż na stercie. Pamięć na stercie jest alokowana na żądanie (mallock/new itp). Natomiast pamięć na stosie jest alokowana podczas skoku do funkcji. Dlatego zanim program wykona pierwszą instrukcję w funkcji to ta pamięć bedzie już zaalokowana. Co prawda program się nie skompiluje gdy sprobujesz w pierwszej linicje odwołać się do zmiennej zadeklarowanej później, ale ta pamięć gdzieś tam jest i teoretycznie da się ją użyć. Nie jest to oczywiście rozsądne, bo to gdzie będzie umieszczona zmienna zależy od implementacji i oczywiście może być zmienione przez optymalizację.
Można hobbistyczno/eksperymentalnie sobie sprobować zobaczyć.
Tutaj przykłąd takiego dostępu w moim środowisku (z totalnie wyłączoną optymalizacją)

void test()
{
    int a = 30;         // Zmienna gdzieś na stosie
    int* a_ptr = &a;
    int* b_ptr = &a + 1; // U mnie wychodziło, że 'b' jest na stosie przesunięte od 'a' o 4 byte (rozmiar int) wiec wystarczy dodać 1 (bo wskaźnik jest int)
                        // To o ile trzeba przesunąc może nam zasugerować wartość &b - &a
    
    *b_ptr = 33;        // Odwołanie się do zmiennej 'b' zannim została zadeklarowana - niebezpieczne i działanie zależy od środowiska
    int b;              // Ta zmienna też bedzie prawdopodobnie na stosie gdzieś
                        // Będzie ona prawdopodobnie gdzieś po 'a'
    
    std::cout << "a address: " << &a << std::endl;
    std::cout << "b address: " << &b << std::endl;
    std::cout << "a_ptr address: " << &a_ptr << std::endl;
    std::cout << "b_ptr address: " << &b_ptr << std::endl;
    std::cout << "a - b (distance): " << (&b - &a) << std::endl;
    std::cout << "a_ptr value: " << *a_ptr << std::endl;
    std::cout << "b_ptr value: " << *b_ptr << std::endl;
    std::cout << "b value: " << b;
}

:Przykładowy mój run:

a address: 0x7a58a02bab38
b address: 0x7a58a02bab3c
a_ptr address: 0x7a58a02bab40
b_ptr address: 0x7a58a02bab48
a - b (distance): 1
a_ptr value: 30
b_ptr value: 33
b value: 33 


Nie wiem jaki jest Twój poziom znajomości assemblera. Jeśli znasz podstawy, to wiele IDE często pozwalają podejrzeć, jake instrukcje zostają wygenerowane. Można więc dosyć łatwo wpisać int tab[10][12] w funkcje i zobaczyć jak faktycznie bedzie to wyglądać.

komentarz 9 stycznia 2021 przez ceyej64281 Nowicjusz (130 p.)

Dzięki za odpowiedzi, ciekawe.

Jaka więc będzie tu odpowiedź? Mi pasują wszystkie, zastanawiam się czy ostatnia jest prawidłowa.

komentarz 9 stycznia 2021 przez ceyej64281 Nowicjusz (130 p.)
Jak by nie było widać to link do zdj.: https://ibb.co/mJg790F

Podobne pytania

0 głosów
1 odpowiedź 55 wizyt
pytanie zadane 28 kwietnia 2020 w C i C++ przez Atman Użytkownik (810 p.)
0 głosów
1 odpowiedź 101 wizyt
pytanie zadane 22 listopada 2018 w C i C++ przez jakubkoksik Początkujący (260 p.)
+2 głosów
2 odpowiedzi 11,020 wizyt

87,976 zapytań

136,557 odpowiedzi

304,510 komentarzy

58,337 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...