C przekroczenie rozmiaru tablicy

0

Witam! Chcę zapytać o poprawność kilku przypadków.
Tworzę pięcioelementową tablicę char. Za pomocą funkcji strcpy przypisuję do niej ciąg 11 znaków. Program wypisuje mi cały ciąg, a nie tylko pierwsze 4 znaki.

int main() {
	char tab[5];
	strcpy(tab, "dlugiciag");
	printf("%s\n", tab);
} 

Druga sytuacja podobna ale z użyciem wskaźnika i funkcji malloc.

int main() {
	char *dwa;
	dwa = malloc(4*sizeof(char));
	strcpy(dwa, "jeszczedluzszyciagznakow");
	printf("%s\n", dwa);
}

W obu przypadkach zostaje wypisany cały ciąg, a nie tylko ograniczony rozmiarem tablicy. Kompilator nie zwraca żadnych uwag podczas kompilacji. Czy można to stosować do "poszerzania" tablic, czy jest to niepoprawne i powinno się tego unikać?

0

Zaczynasz pisać poza rozmiarem tablicy, nie zostaje ona automatycznie powiększona.
W większości przypadków skończy się to błędem podczas działania programu (możesz np.nadpisać inną tablicę czy zmienną).

0

Jest to bezwzględny błąd i w zależności od środowiska, w którym została uruchomiona aplikacja i szczęścia:

  1. wszystko może zadziałać poprawnie,
  2. program będzie działał dalej, ale został uszkodzony inny obiekt i taki błąd będzie później niesamowicie trudny do wykrycia,
  3. aplikacja malowniczo się wyłoży.
0

Program wypisuje mi cały ciąg, a nie tylko pierwsze 4 znaki.

A dlaczego miał by skończyć po 4 znakach. W C to po prostu ASCIIZ, czytamy dopóki nie mamy #0.

Czy można to stosować do "poszerzania" tablic, czy jest to niepoprawne i powinno się tego unikać?

Generalnie to:
1.Jeżeli jest to tablica globalna, to pewnie nadpiszesz sobie inną zmienną globalną (która jest deklarowana po twojej tablicy ew. parę).
2.Jeżeli jest to tablica lokalna, to zapewne nadpiszesz inne zmienne lokalne, które są za twoją tablicą i być może to co jest za szczytem tablicy (czyli po wywołaniu podprogramu twoja tablica może zawierać coś innego niż ci się wydaje).
3.Jeżeli zrobisz tak z malloc to ciężko przewidzieć co nadpiszesz. Najprawdopodobniej będzie to coś innego co się dynamicznie alokuje w pamięci np. obiekty.
Jeżeli tobie to nie przeszkadza (ale powinno) to używaj, prędzej czy później skończy się to jakimś crashem. Jako tablicę dynamiczną używaj raczej wektorów z C++.

Możesz sobie spróbować do pierwszego przykładu dodać wywołanie jakieś tam procedury z parametrami i po powrocie wypisać zawartość twojej tablicy, pewnie będzie zawierać adres powrotu z procedury.

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