Pamiętaj o rozmiarze bufora w C

Ten wpis jest częścią mojego starego bloga, prowadzonego w latach 2005-2007 pod adresem dragonee.jogger.pl. Został on zachowany w celach archiwizacyjnych i niekoniecznie reprezentuje moje bieżące stanowisko na dany temat.

… czyli jak mała literówka może stać się źródłem poważnego problemu.

Na sam początek – mam procesor na architekturze x86 i gcc 4.1.2, nie ręczę za to, że na innych program przedstawiony poniżej będzie tak samo działać. U mnie i u mojego przyjaciela jednak właśnie tak było.

Przyjaciel mój odezwał się do mnie z problemami ze swoim programem sortującym. Po małym połataniu kodu, natrafiliśmy na nieskończoną pętlę, która w tym kodzie wystąpić nie miała prawa, a jednak w jakiś sposób wystąpiła. W feralnej pętli przy każdej iteracji zmienna iteratora miała stałą wartość, pomimo dekrementacji wykonywanej na niej za każdym razem. Co więc nadpisywało zmienną? Wyobraźmy sobie taki przykład:

#include <stdio.h>
int main() {

        int arr[2];
        int a, b, c, d, i;

        for(i = 0; i < 6; i++)
                arr[i] = i;

        printf("%d %d %d %d\n", a, b, c, d);

        return 0;
}

Po skompilowaniu i uruchomieniu:

dragonee@hikari ~/dev 12:50:13 $ ./a.out
2 3 4 5
dragonee@hikari ~/dev 12:50:16 $

Wyjście poza tablicę nadpisuje następne zmienne. Nieprzyjemna sprawa, bo w ten sposób możemy przepisać te zmienne, które będą niezbędne do działania kodu. Albo trafimy dokłanie w taki punkt, który skończy się nieskończoną pętlą. Segmentation fault w tym przypadku wydaie się najprzyjemniejszym zakończeniem tego programu, bo od razu będziemy wiedzieć, że coś niedobrego z pamięcią się dzieje.

Niestety, my natrafiliśmy na nieskończoną pętlę. Zmienna iteracyjna była pierwszą po tablicy, a wartość, którą wpisywaliśmy do iteratora w tablicy wskazywała dokładnie na iterator. Dzięki temu mimo dekrementacji nic się nie zmieniało, a program działał i działał i działał…

Aby wszystko zadziałało, wystarczyło zwiększyć tylko rozmiar tablicy o 1 element. Na co trafiliśmy po godzinie wpatrywania się w 50 linii kodu.

Tags:
4 komentarze
  1. Lipiec 8, 2007
  2. Lipiec 8, 2007
  3. Lipiec 8, 2007
  4. Lipiec 8, 2007

Leave a Reply

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *