C - czy trzeba domyślnie zerować tablice znakowe o statycznym rozmiarze?

Newb
2011-09-21 21:44
Newb
0

Witam,
Wiem, że dynamiczne tablice znakowe w C rezerwowane za pomocą malloc nie są domyślnie zerowane (można użyć calloc albo malloc + bzero). Jak to się ma do tablic statycznych o rozmiarze n? Czy kompilator gwarantuje, że składają się z samych zer czy też trzeba je potraktować bzero dla pewności?

Pozdrawiam,

Pozostało 580 znaków

Rev
2011-09-21 21:46
Rev
Moderator

Rejestracja: 12 lat temu

Ostatnio: 6 dni temu

0

Statycznych tablic nie trzeba ręcznie zerować.


Pozostało 580 znaków

2011-09-21 21:54

Rejestracja: 9 lat temu

Ostatnio: 2 lata temu

0

To zależy, jeżeli to są zmienne globalne to są inicjowane zerami, jeżeli lokalne to takiej pewności nie ma.


Pozostało 580 znaków

Newb
2011-09-22 00:42
Newb
0

Ok, czyli zeruje tylko lokalne zmienne tablicowe. Dzięki.

Globalne.Te tworzone na stosie będą zawierać śmieci. - MasterBLB 2011-09-22 01:02
lokalne :P - krwq 2011-09-22 01:21
Nie, globalne są zerowane, lokalne nie. - byku_guzio 2011-09-22 01:28
"czyli zeruje tylko lokalne zmienne tablicowe" - lokalne zeruje bo globalnych nie musi - krwq 2011-09-22 01:37
Dodatkowo nie trzeba tego robić żadną funkcją - wystarczy coś takiego int tab[100] = {0}; (całość zostanie wyzerowana) - byku_guzio 2011-09-22 01:45
myślałem, że to powoduje ustawienie tylko pierwszego elementu, a reszta jest niezdefiniowana, ale sprawdziłem i rzeczywiście działa - to jest w nowym standardzie czy zawsze tak było? - krwq 2011-09-22 09:51

Pozostało 580 znaków

2011-09-22 07:52

Rejestracja: 16 lat temu

Ostatnio: 1 minuta temu

0

jeśli zaraz potem będzie sprintf do tej tablicy albo coś podobnego, to i zerować nie trzeba…

Pozostało 580 znaków

2011-09-22 09:00

Rejestracja: 8 lat temu

Ostatnio: 15 godzin temu

0

W tym temacie objawia się pierwszy sygnał poważnej schizofrenii u twórców C/C++.


Szacuje się, że w Polsce brakuje 50 tys. programistów

Pozostało 580 znaków

2011-09-22 09:15

Rejestracja: 8 lat temu

Ostatnio: 1 godzina temu

1

Dobrze jest inicjalizować zawsze i żyć spokojnie :P

nie jeśli zaraz wypełnisz zmienną inną wartością… - Azarien 2011-09-22 09:30

Pozostało 580 znaków

2011-09-22 09:29

Rejestracja: 16 lat temu

Ostatnio: 1 minuta temu

0

ma to uzasadnienie:

  1. globalne: to nic nie kosztuje, minimalne spowolnienie ładowania się programu (albo żadne, jeśli to system operacyjny zeruje)
  2. lokalne: byłoby za dużym marnotrawstwem, nie zawsze potrzebujemy zerowania jeśli zaraz przypisujemy tam jakąś wartość.
  3. malloc nie, ale calloc tak. możesz sobie wybrać.
  4. jak w punkcie 2.
  5. i tylko tu mamy lekką schizofrenię

dla porównania C#:

  1. brak globalnych, są pola ale te podpadają pod punkt 5.
  2. lokalne nie są zerowane, ale kompilator nie pozwoli nam na odczytanie niezainicjowanej wartości (czasem to przeszkadza). podobnie alokacja przez stackalloc (bezpośredni odpowiednik tablicy w C) nie zeruje pamięci.
  3. brak potrzeby ręcznej alokacji pamięci, ale jak ktoś potrzebuje, to AllocHGlobal również nie zeruje obszaru
  4. trudno o bezpośredni odpowiednik; zarządzane tablice są zerowane, ale to bardziej punkt 5.
  5. jak w C.

jak widzimy, w większości przypadków mamy takie samo zachowanie.

Pozostało 580 znaków

2011-09-22 10:10

Rejestracja: 8 lat temu

Ostatnio: 15 godzin temu

0
Azarien napisał(a)

(ciach)

  1. lokalne nie są zerowane, ale kompilator nie pozwoli nam na odczytanie niezainicjowanej wartości (czasem to przeszkadza). podobnie alokacja przez stackalloc (bezpośredni odpowiednik tablicy w C) nie zeruje pamięci.

Tu jest nieścisłość. Kompilator przepuszcza takie odczyty (być może daje warning, chociaż wątpie), program wywala się dopiero w czasie działania - ale zdaje się tylko w trybie debug?

W Visual C++ niezainicjowane zmienne można wykryć - mają specyficzne wartości (kompilator się o to troszczy - w trybie debug). Z tego co pamiętam, wstawiane są automatem kody sprawdzające takie odczyty.


Szacuje się, że w Polsce brakuje 50 tys. programistów
edytowany 2x, ostatnio: vpiotr, 2011-09-22 10:58

Pozostało 580 znaków

2011-09-22 10:45

Rejestracja: 16 lat temu

Ostatnio: 1 minuta temu

0

Tu jest nieścisłość. Kompilator przepuszcza takie odczyty (być może daje warning, chociaż wątpie), program wywala się dopiero w czasie działania - ale zdaje się tylko w trybie debug?

stackalloc jest unsafe. zauważ, że zwracana zmienna jest tylko wskaźnikiem (np. int*) więc nawet indeksy nie są sprawdzane i możesz bez problemu wyjechać poza zasięg i wywalić program.
w momencie użycia unsafe, wyłączasz mechanizmy kontrolne i bierzesz na siebie odpowiedzialność, że kod jest prawidłowy. w C jesteś zawsze w trybie „unsafe”.

Nie zwróciłem uwagi że to dotyczy C#... - vpiotr 2011-09-22 10:56

Pozostało 580 znaków

1 użytkowników online, w tym zalogowanych: 0, gości: 0, botów: 1

Robot: CCBot