Dynamiczna alokacja pamięci – usunięcie wskaźników z kodu

0

Witam serdecznie, jestem początkującym programistą, który zmierzył się z problematyką wskaźników. Niestety żaden materiał w internecie do tej pory nie wyjaśnił mi jakie są rzeczywiście zalety korzystania ze wskaźników jeśli chodzi o tablice. Ciągle czytam, że po to aby użytkownik sam mógł zdecydować o wielkości tablicy jeszcze przed kompilacją, ale czy nie można tego zrobić bez pomocy wskaźników? Czym się różni ten kod:

    int *tab;
    int ile;

    tab = new int [ile];

    cin>>ile;

    for(int i=0;i<ile;i++){
        tab[i]=i;
        cout<<tab[i]<<endl;
    }
    delete [] tab;
    tab = NULL;

Od tego:

 int ile;
    cin>>ile;
    int tab[ile];

    for(int i=0;i<ile;i++)
    {
        tab[i]=i;
        cout<<tab[i]<<endl;
    }

Zarówno w pierwszym jak i w drugim przypadku nie deklarowałem wielkości tablicy przed kompilacją. Będę bardzo wdzięczny gdy ktoś mi to wreszcie wytłumaczy. dziękuję

1

Pierwszy przypadek to UB. Zmienna ile nie ma nadanej wartości początkowej, a jest użyta do alokacji pamięci.
https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete/

4

W prawdziwym współczesnym C++ unika się jawnego używania operatora new i surowych wskaźników.
Jeśli nie musisz używać API C to należy używać:

  • std::array dla tablic o statycznie określonym rozmiarze
  • std::vector dla tablic o dynamicznym rozmiarze
  • std::unique_ptr std::make_unique - do tworzenia i zarządzenia obiektów używanych przez jedn obiekt
  • std::shared_ptr std::make_shared - do tworzenia i zarządzenia obiektów używanych przez wiele obiektów.

Zaleta:
odpowiedzialność za zarządzanie pamięcią przechodzi na kompilator i bibliotekę standardową, co ogranicza możliwość wycieków pamięci.

0

Ten drugi kod w ogóle się skompiluje? Przynajmniej w visualu wywala błąd.

4
int main() {
    int ile;
    cin >> ile;
    vector<int> tab(ile);
    generate(tab.begin(), tab.end(), [n = 0] () mutable {
    	return n++;
    });
	copy(tab.begin(), tab.end(), ostream_iterator<int>(cout, " "));
}

I żadne pętle, wskaźniki, new, delety, NULLe nie są potrzebne.

0
Afars napisał(a):

Ten drugi kod w ogóle się skompiluje? Przynajmniej w visualu wywala błąd.

W C++ nie powinien, bo korzysta z VLA, które są dostępne w niektórych kompilatorach podczas kompilacji bez pełnej zgodności ze standardem C++.

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