Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Małe pytanko odnośnie tablic

Ostatnio zmodyfikowano 2016-12-07 22:39
Autor Wiadomość
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:
C/C++
#include <iostream>
int main()
{
    int w;
    cin >> w;
    int tablica[ w ];
    return 0;
}
jest błędne i powinno wyglądać tak:
C/C++
#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.
P-154560
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!
P-154562
carlosmay
» 2016-12-05 23:05:35
http://stackoverflow.com​/questions/14075194​/variable-length-arrays-vla-in-c-and-c

Pierwszy kod będzie ok, jeśli rozmiar tablicy będzie
constexpr
, ponieważ tak mówi standard.

Jeśli rozmiar ma być ustalany w trakcie wykonania programu, trzeba użyć dynamicznej alokacji (przykład 2).
Oczywiście należy zwolnić pamięć.
Jeszcze lepiej korzystać z std::vector

up: spodziewałbym się @pekfos krótkiego zdania, ale taki wykład. No no ;)

P-154564
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
P-154635
« 1 »
  Strona 1 z 1