Jaka jest różnica między tablicą statyczną a tablicą dynamiczną w C ++?
Muszę zrobić zadanie dla mojej klasy i mówi, aby nie używać tablic statycznych, tylko tablice dynamiczne. Zajrzałem do książki i online, ale nie rozumiem.
Myślałem, że statyczny został utworzony w czasie kompilacji, a dynamiczny w czasie wykonywania, ale mogę pomylić to z alokacją pamięci.
Czy możesz wyjaśnić różnicę między tablicą statyczną a tablicą dynamiczną w C ++?
Odpowiedzi:
Tablice lokalne są tworzone na stosie i mają automatyczny czas przechowywania - nie musisz ręcznie zarządzać pamięcią, ale są niszczone, gdy funkcja, na której się kończy, się kończy. Koniecznie mają stały rozmiar:
int foo[10];
Tablice utworzone za pomocą
operator new[]
mają dynamiczny czas trwania i są przechowywane na stercie (technicznie rzecz biorąc, „magazyn darmowy”). Mogą mieć dowolny rozmiar, ale musisz je przydzielić i zwolnić, ponieważ nie są częścią ramki stosu:int* foo = new int[10]; delete[] foo;
źródło
int* foo = new int[N]
te, które musisz mieć dladelete
siebie, dlatego uważaj w przypadku wyjątku. Tablice statyczne nie mają tych problemów.static jest słowem kluczowym w C i C ++, więc zamiast ogólnego terminu opisowego, static ma bardzo specyficzne znaczenie, gdy zostanie zastosowane do zmiennej lub tablicy. Aby pogłębić zamieszanie, ma trzy różne znaczenia w oddzielnych kontekstach. Z tego powodu tablica statyczna może być stała lub dynamiczna.
Pozwól mi wyjaśnić:
Pierwsza jest specyficzna dla C ++:
Dwa są dziedziczone po C:
w funkcji zmienna statyczna to taka, której lokalizacja pamięci jest zachowywana między wywołaniami funkcji. Jest statyczny, ponieważ jest inicjowany tylko raz i zachowuje swoją wartość między wywołaniami funkcji (użycie statyki powoduje, że funkcja nie jest ponownie wprowadzana, tj. Nie jest bezpieczna dla wątków)
zmienne statyczne zadeklarowane poza funkcjami to zmienne globalne, do których można uzyskać dostęp tylko z poziomu tego samego modułu (plik z kodem źródłowym z innymi # dołączeniami)
Pytanie (myślę), które chciałeś zadać, dotyczy różnicy między tablicami dynamicznymi a tablicami ustalonymi lub kompilowanymi w czasie. To jest łatwiejsze pytanie, tablice w czasie kompilacji są określane z góry (podczas kompilacji programu) i są częścią ramki stosu funkcji. Są przydzielane przed uruchomieniem funkcji głównej. tablice dynamiczne są przydzielane w czasie wykonywania za pomocą słowa kluczowego „new” (lub rodziny malloc z C), a ich rozmiar nie jest z góry znany. alokacje dynamiczne nie są automatycznie czyszczone, dopóki program nie przestanie działać.
źródło
new[]
operatora, jak to się dzieje, że rozmiar nie jest znany do czasu uruchomienia? ieint* p = new int[10]
Myślę, że semantyka używana na zajęciach jest myląca. Przez „statyczny” prawdopodobnie rozumie się po prostu „stały rozmiar”, a przez „dynamiczny” prawdopodobnie chodzi o „zmienny rozmiar”. W takim przypadku tablica o stałym rozmiarze może wyglądać następująco:
int x[10];
a „dynamiczna” byłaby po prostu dowolną strukturą, która pozwala na zwiększenie lub zmniejszenie podstawowej pamięci w czasie wykonywania. W większości przypadków
std::vector
wystarczy klasa ze standardowej biblioteki C ++. Użyj tego w ten sposób:std::vector<int> x(10); // this starts with 10 elements, but the vector can be resized.
std::vector
zostałoperator[]
zdefiniowany, więc można go używać z tymi samymi semantyki jako tablica.źródło
new int[10]
Tablice statyczne są przydzielane do pamięci w czasie kompilacji, a pamięć jest przydzielana na stosie. Natomiast tablice dynamiczne są przydzielane w czasie wykonywania, a pamięć jest przydzielana ze sterty.
int arr[] = { 1, 3, 4 }; // static integer array. int* arr = new int[3]; // dynamic integer array.
źródło
Ważne jest, aby mieć jasne definicje tego, co oznaczają terminy. Niestety wydaje się, że istnieje wiele definicji tego, co oznaczają tablice statyczne i dynamiczne.
Zmienne statyczne to zmienne zdefiniowane przy użyciu statycznej alokacji pamięci . To jest ogólna koncepcja niezależna od C / C ++. W C / C ++ możemy tworzyć zmienne statyczne o zasięgu globalnym, plikowym lub lokalnym w następujący sposób:
int x[10]; //static array with global scope static int y[10]; //static array with file scope foo() { static int z[10]; //static array with local scope
Zmienne automatyczne są zwykle implementowane przy użyciu alokacji pamięci opartej na stosie . Tablicę automatyczną można utworzyć w C / C ++ w następujący sposób:
foo() { int w[10]; //automatic array
Co te tablice,
x, y, z
iw
mają wspólną cechą jest to, że wielkość dla każdego z nich jest stała i jest określona w czasie kompilacji.Jednym z powodów, dla których ważne jest zrozumienie różnicy między tablicą automatyczną a tablicą statyczną, jest to, że statyczna pamięć jest zwykle zaimplementowana w sekcji danych (lub sekcji BSS ) pliku obiektowego, a kompilator może używać adresów bezwzględnych, aby uzyskać dostęp do tablic co jest niemożliwe w przypadku przechowywania na stosie.
Zwykle pod pojęciem tablicy dynamicznej nie rozumie się takiej, której rozmiar można zmieniać, ale zaimplementowaną przy użyciu dynamicznej alokacji pamięci o stałym rozmiarze określanym w czasie wykonywania. W C ++ odbywa się to za pomocą
new
operatora .foo() { int *d = new int[n]; //dynamically allocated array with size n
Ale możliwe jest utworzenie automatycznej tablicy z rozmiarem poprawek zdefiniowanym w czasie wykonywania za pomocą
alloca
:foo() { int *s = (int*)alloca(n*sizeof(int))
W przypadku prawdziwej tablicy dynamicznej należy użyć czegoś takiego jak
std::vector
w C ++ (lub tablicy o zmiennej długości w C ).Co oznaczało zadanie w pytaniu PO? Myślę, że jest jasne, że to, co było pożądane, nie było tablicą statyczną lub automatyczną, ale taką, która albo wykorzystywała dynamiczną alokację pamięci za pomocą
new
operatora, albo tablicę o nie ustalonym rozmiarze, używając npstd::vector
.źródło
Myślę, że w tym kontekście oznacza to, że jest statyczny w tym sensie, że rozmiar jest stały. Użyj std :: vector. Posiada funkcję resize ().
źródło
Możesz mieć tablicę pseudo dynamiczną, w której rozmiar jest ustawiany przez użytkownika w czasie wykonywania, ale potem jest ustalany.
int size; cin >> size; int dynamicArray[size];
źródło
Tablica statyczna :
Tablica dynamiczna:
źródło
Tak, prawda, tablica statyczna jest tworzona w czasie kompilacji, podczas gdy tablica dynamiczna jest tworzona w czasie wykonywania. Jeśli chodzi o różnicę w ich lokalizacjach w pamięci, statyczne znajdują się na stosie, a dynamiczne są tworzone na stercie. Wszystko, co znajduje się na stercie, wymaga zarządzania pamięcią, dopóki nie jest obecny moduł wyrzucania elementów bezużytecznych, jak w przypadku platformy .net, w przeciwnym razie istnieje ryzyko wycieku pamięci.
źródło
Tablica statyczna: wydajność. Nie jest wymagana dynamiczna alokacja ani cofanie alokacji.
Tablice zadeklarowane w C, C ++ w funkcji łącznie z modyfikatorem statycznym są statyczne. Przykład: static int foo [5];
źródło
statyczne aranżacje oznaczają podawanie elementów z boku tablicy
dynamiczne znaki aranżacyjne bez podawania elementów po stronie tablicy
przykład:
char a[10]; //static array char a[]; //dynamic array
źródło