Tablica statyczna, przyczyna określenia rozmiaru

0

Dzień dobry.

Dlaczego C++ musi znać rozmiar tablicy w momencie kompilacji żeby móc ją stworzyć? Mowa o tablicach statycznych. Czy chodzi o jakieś optymalizacje? Dlaczego można tworzyć tylko tablice dynamicznie o rozmiarze określonym przez użytkownika programu?

Pozdrawiam
M.

2

Przecież masz vector<> nie musisz znać rozmiaru podczas tworzenia.
Może zastanów się nad sensem Tablica statyczna jakim cudem jej rozmiar zależy od decyzji użyszkodnika?

1

Można stworzyć dynamicznie statyczną tablicę na stosie, standardowo się tego nie zaleca robić.
Możesz użyć alloca, ewentualnie dodać wstawkę assemblera gdzie odejmiesz od rsp tyle bajtów ile potrzebujesz.

1

Variable Length Array, co jeśli zmienna jakimś trafem podmieni wartość na 0? Tablica się utworzy, ale powodzenia w debugowaniu dalszej części kodu

2

Tablica statyczna języków jak C/ASM jest bardzo konkretnym obszarem/rozmiarem pamieci, który pojawia sie już w momencie ładowania programu EXE
Więc musi być znana (i zainicjowana, zerami lub czymś innym) przez pierwszym rozkazem maszynowym jaki będzie wykonany.

1

Jak zwykle rozmawiam z betonami.

Nie umiecie czytać? Moje pytanie nie było podyktowane chęcią ominięcia problemu tablic statycznych. Pytanie było jasne: dlaczego

Ale widać na tym forum nikt nie posiadł umiejętności czytania ze zrozumieniem. Same betony. Pozdrawiam.

4

Kompilator sobie statycznie przypisuje położenie na stosie w instrukcjach wygenerowanych, a obejście tego to zastosowanie wskaźników na stos, przesunięcie wierzchołka stosu i traktowanie jak dynamicznie zaalokowanego.

I czasem kompilator adresuje sobie od ramki w dół, a czasem od wierzchołka stosu w górę, co potem jakieś komplikacje mogą wystąpić.

Adres ramki wskazuje na adres stosu przy wchodzeniu do funkcji, a wierzchołek po zarezerwowaniu danych na stosie.

I teraz jeśli w programie relatywnie jest obliczany adres,
ramka +8 to pierwszy int
ramka +16 drugi
to jak na początku damy o zmiennej długości tablicę, to nam się adresy relatywne nie będą zgadzać.
Jak damy na końcu to do każdej tablicy o zmiennej długości musimy zwracać absolutny adres tego położenia na stosie, bo nigdy nie wiem gdzie będzie się zaczynał, bo przed tą tablicą mogła być następna inna o zmiennej wielkości.

A z tego co zauważyłem to kompilatory często robią odwrotnie i obliczają relatywny adres względem wierzchołka stosu, adresy poszczególnych elementów na stosie.

2

laczego można tworzyć tylko tablice dynamicznie o rozmiarze określonym przez użytkownika programu?

na gcc może i można ale czy się powinno? Gcc ma VLA z automatu inni jak pamiętam nie, to chyba gdzieś było w C99 później się z tego wycofano(powodów możesz sobie poszukać). Sam zarzucasz ludziom g**no a sam zapodajesz takie.

No nie bo to nijak nie tłumaczy. Na pytanie dlaczego nie odpowiada się w sposób retoryczny "może zastanów się...". Pytanie było konkretne. Oczekiwałem konkretnej logicznej i technicznej odpowiedzi. Dostałem g... Ale to normalne na tym forum.

Dostałeś dokładna odpowiedź ale nie znasz c++ to mogłeś powiedzieć od razu. Ale najłatwiej obrazić.
masz pierwszy lepszy temat z SO o vla i static
https://stackoverflow.com/questions/62107332/difference-between-dynamically-allocated-arrays-and-static-arrays

6

Przecież takie jest znaczene tych słów. Statyczny - znany w czasie kompilacji, niezmienny. Dynamiczny - nieznany w czasie kompilacji, może być np. w każdym obrocie pętli inny. Równie dobrze możesz pytać czy można zrobić klasę, która nie jest typem.

1

Przepraszam niepotrzebnie się uniosłem.

Moje pytanie dotyczyło tego, po co w ogóle są tablice statyczne. Jakie były przyczyny tego, że zdecydowano się na alokację statyczną i dynamiczną. Jakby nie można było wszystkiego zrobić dynamicznie. A jeżeli jednak nie jaka jest tego techniczna przyczyna :)

2

@mpaw powiem, ci że my też tego do końca nie wiemy, to trudne trochę jest.
Heap program sobie dostaje stronę pamięci od systemu, i malloc, heap allocator mają swój algorytm rozporządzania danych na tej stronie.

A na stosie nie masz takich dynamicznych menadżerów pamięci jak malloc i tam lepiej jak statycznie wszystko jest, lub jak jesteś reverse enignnerem to możesz czasem przewidzieć kompilację i zmusić program do działąnia dla ciebie, ale to nie będzie przenośnę i jest obardzone unefinded behavior.

7

Wydajność: dużo łatwiej takie tablice trzymać przy innych danych, zmniejszając liczbę skoków do L2/L3/RAM-u, które są kosztowne i konieczne jeśli masz wskaźniki. Tablice o znanej wielkości możesz też łatwo wpakować na stos lub do binarki.

4

Wszystko się sprowadza do kompromisu pomiędzy tym ile wolności daje się programiście, zabierając mu komfort. Tworząc tablicę w wyżejpoziomowych językach nie musisz się tym martwić, ale też nie możesz zmienić implementacji takiej tablicy/kolekcji pod spodem (np w PHP tablica jest pod spodem zawsze zaimplementowana jako hashmapa z kluczami string|int zachowująca kolejność, i nie można stworzyć swojej implementacji polegając na swoich bajtach, tak jak się da np w C).

Mając dostęp do tak niskopoziomowego rozwiązania, nie musisz polegać na persystencji wybranej przez kompilator/język/runtime/biblioteki. Cenę jaką płacisz, jest oczywiście to że sam musisz to napisać i utrzymać.

3
mpaw napisał(a):

Moje pytanie dotyczyło tego, po co w ogóle są tablice statyczne. Jakie były przyczyny tego, że zdecydowano się na alokację statyczną i dynamiczną. Jakby nie można było wszystkiego zrobić dynamicznie. A jeżeli jednak nie jaka jest tego techniczna przyczyna :)

Statyczna ma szczególnie prosta implementację w języku maszynowym. A wręcz brak implementacji, rzecz się dzieje podczas ładowania programu, przed przekazaniem pierwszego JMP do kodu.
I jedyną dostępną w C inicjacją inną niż zerową (w C++ są opcjonalne konstruktory, czyli kod)

masz dobrą intuicję, nie jest to konieczne. Wiele nowszych języków nie ma tego wynalazku,. i nie ma z tego jakiegoś cierpienia.

Jest wręcz na odwrót: wielość modeli pamięci w C to duży problem.
Jakby wiedzieć na 100%,w C "acha, ten blok pamięci był alokowany dynamicznie, więc zrobię mu free", wiele rzeczy by się uprościło.

To nawet nie jest tak, ze GC w Javie czy C# to wielkie lekarstwo. Bo rodzaj C, czy C++, w którym by była gwarancja "każdy obszar pamięci nie ma innego pochodzenia niż dynamiczne", świat byłby prostszy. Nawet z free() / delete

Żegnaj o pamięci statyczna, nie będzie nam ciebie brakowało [^]
:(

1

Pamięć statyczna to iluzja. Przed załadowaniem system operacyjny robi alokacje dynamiczną, czyli musi znaleźć wolne miejsce w RAM i zarezerwować ja dla procesu, którego kod i dane zostaną następnie wczytane z pliku exe/elf. OS odpowiada za alokację i zwolnienie tej pamięci i robi to dynamicznie. Z perspektywy procesu ona jest statyczna i nie musi się on martwić o jej zarządzanie. Na wstępie proces dostaje w prezencie ileś tam stron RAMu, która powinna mu wystarczyć. Jak chce więcej to musi później o nią poprosić (malloc, calloc, new, etc.) i oddać kiedy jej nie potrzebuje (free, delete).

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.