Małe pytanko odnośnie tablic
Ostatnio zmodyfikowano 2016-12-07 22:39
adms Temat założony przez niniejszego użytkownika |
Małe pytanko odnośnie tablic » 2016-12-05 21:47:17 Gdzieś przeczytałem że tworzenie tablic w ten sposób: #include <iostream> int main() { int w; cin >> w; int tablica[ w ]; return 0; }
jest błędne i powinno wyglądać tak: #include <iostream> int main() { int w; cin >> w; int * tablica = new int[ w ]; return 0; }
Mógłby mi ktoś zwięźle wytłumaczyć dlaczego? Muszę dodać, że korzystałem z tego "błędnego" sposobu od długiego czasu i nie spotkałem się z żadnymi problemami. |
|
pekfos |
» 2016-12-05 23:03:39 Oba sposoby są błędne, a jeśli poprawić ten drugi, to nawet to nie będzie to samo, co robiłeś pierwszym zapisem.
"Błędny" zapis działa, bo kompilator to wspiera. Tzn ten jeden konkretny kompilator w tej konkretnej wersji to wspiera. Inny już nie musi, bo to nie jest częścią standardu C++. To istnieje w zasadzie tylko dlatego, że to było poprawne w C. Dokładniej w C99, w nowszym standardzie C11 ta funkcjonalność już nie musi być wspierana.
Drugi zapis jest błędny, bo to nie jest zamiennik jeden do jednego. Nie możesz sobie od tak zmienić int[] na int*, bo zasada działania jest zupełnie inna. new alokuje pamięć, która jest do twojej dyspozycji aż sam się jej pozbędziesz, albo pozbędzie się jej system operacyjny (razem z twoim programem). Do każdej alokacji przez new musi być dealokacja przez delete (lub delete[], jedno z dwóch, drugie spowoduje katastrofę). Bez tego będziesz mieć wycieki pamięci i w końcu możesz tej dodatkowej pamięci już od systemu nie dostać. Dealokacja może być przeprowadzona automatycznie, jeśli będziesz używać wskaźników inteligentnych, ale nawet wtedy to nie będzie to samo co int[]. Dynamiczna alokacja przydziela ci pamięć z obszaru sterty i pod tym względem, ten zapis jest "lepszy". "Błędny" zapis dawał ci pamięć z obszaru stosu, który jest znacznie bardziej ograniczony. Zażądaj kilku megabajtów, a program się niechybnie wysypie. Z kolei ze sterty możesz żądać (i dostać) tyle pamięci ile tylko architektura udźwignie i system zdoła znaleźć.
A jeśli chcesz zapisu, którego naprawdę się nikt nie przyczepi, to użyj std::vector<int> z STL. Alokuje dynamicznie, zwalnia pamięć po wyjściu z zakresu i masz możliwość zmniejszania i zwiększania ilości elementów w środku.
Tzn nikt się nie przyczepi, jeżeli faktycznie będziesz używać tego wtedy, kiedy trzeba. Nie przestawiaj się od razu na 'lepszy pod każdym względem' std::vector<>, bo tablice zwykłe dalej są standardową częścią C++ i są nią nie bez powodu (tzn te o stałym rozmiarze). Alokacja dynamiczna pyta o wszystko system operacyjny a ten musi ci wolną pamięć zlokalizować, co swój czas trwa. Alokacja na stosie, to zmiana jednej liczby, która jest zawsze procesorowi pod ręką. W skrajnych przypadkach, różnice wydajnościowe będą gigantyczne. Tak więc wybieraj rozwiązania zależnie od sytuacji, duh! |
|
carlosmay |
» 2016-12-05 23:05:35 |
|
adms Temat założony przez niniejszego użytkownika |
» 2016-12-07 22:39:38 @pekfos, dzięki. Pomogłeś bardzo! Jesteś wielki! <3 /zamykam |
|
« 1 » |