Stos, inicjalizacja zmiennych, miejsce zmiennych w pamięci

0

Witam, mam następujące pytanie debug'uje obie programą w C++ pod Visual Studio tak, żeby ogarnać jak to wszystko pracuje i mam następujące pytanie:

kod testowy:

#include <iostream>

using namespace std;

int main(){

	char tablica1[10] = {};
	char tablica2[10] = {};

	cout << sizeof(char) << endl;


	cin >> tablica1;
	cout << tablica1 << endl;

	cin >> tablica2;
	cout << tablica2 << endl;


	return 0;
}

W pamięci zmienne są obok siebie natomiast nurtuje mnie to czemu pomiędzy nimi jest "przerwa" 10 bajtowa.
Np.

tablica1 ma adres 0x0038f77c (początek)
tablica1 ma adres 0x0038f768 (początek)

różnica 20 bajtów - 10 na dane w tablicy = 10 bajtów odstępu i tak jest za każdym razem po ponownym odpaleniu programu (adresy się oczywiście zmieniją, ale różnica pomiędzy adresami zawsze wynosi 20 bajtów)

Czy to z czegoś wynika, że jest to miejsce? Tam oczywiście są jakieś śmieci.
Pytam z ciekawości. Zrobiłem sobie przepełnienie bufora, żeby nadpisać dane w tablicy1 i do tablicy2 wpisałem tekst dłuższy niż jej rozmiar i pod debuggerem widać, że dopiero 21 znak nadpisuje pierwszy element tablicy1. (głównie chodzi mi tu to to czy zmienne nie są na stosie wstawiane zaraz po sobie, kończy się zakres pierwszej zmiennej to zaraz po niej zaczyna się druga itd.).
System 64 bit Win7.
Mam nadzieję, że nie zamotałem za mocno :D.

0

A to nie jest czasem tak że w trybie debug visual studio ma "array safety", tzn specjalnie robi takie dziury żeby program sie nie wysypał (tylko żeby wykrywać buffer overflow)? Jak to odpalisz w release to jest tak samo?

0

No pod release działa to trochę inaczej. Natomiast dziury pomiędzy zmiennymi wynoszą 2 bajty:
np.:

tablica1 ma adres 0x0041f9e4 (początek)
tablica2 ma adres 0x0041f9f0 (początek)

Przy okazji dopytam bo pod release debugger pracuje trochę inaczej, np. ustawiam breakpointy przy deklaracji i inicjalizacji:

char tablica1[10] = {};
char tablica2[10] = {};

W trybie Debug w tych miejscach program się zatrzymuje i podczas krokowego przejścia wiadać, że tablice są inicjowane zerami. W trybie Release natomiast mimo ustawień breakpointów program się NIE zatrzymuje w tych miejscach, a dopiero w lini:

cin >> tablica1; //(gdzie mam kolejny breakpoint)

i dopiero wtedy tablica wypełnia się zerami (jest inicjowana, a wcześniej są jakieś śmieci z pamięci), rozumiem, że chodzi tutaj po prostu o optymalizację i inicjalizację dopiero w momencie przed pierwszym użyciem?

0

Trudno wyrokować, ale bardzo możliwe że tak. Jak chcesz się tak bawić to:

  • kompiluj z wyłączoną optymalizacją
  • najlepiej kompiluj do poziomu asemblera i dopiero analizuj kod

Odstepy między tablicami to moze być zwykły mechanizm obrony przez popularnymi off-by-one, albo wyrównanie (padding) które ma przyspieszyć pracę.
Kompilowanie kodu z optymalizacjami i wstawianie breakpointów jest bez sensu ;]

0

Dzięki za opowiedź i trochę rozjaśnienie sprawy. Pobawię się tym dalej :).

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