dynamiczne alokowanie pamięci vs vector -> wady i zalety

0

Hey, mam do was takie pytanie: uczę się od dłuższego czasu programować w C++ i do tej pory często korzystałem z dynamicznych tablic. Do vectora nie mogłem się długi czas przekonać - miałem swoje powody :)... Jednak ostatnio przebudowałem jeden z moich większych projektów na taki w całości zbudowany na vectorach (zamiast wskaźników) i powiem szczerze, że moje życie się zmieniło ;) - na lepsze ofc.

Mam więc do was pytanie czy są jakieś zalety stosowania dynamicznych tablic zamiast vectora? Czy ja wiem - chodzi mi np. o szybkość/wydajność? Bo ja chwilowo takowych nie widzę...
Czy w waszych projektach korzystacie jeszcze ze wskaźników do alokowania dynamicznych tablic?
pozdrawiam

0

Tablice dynamiczne, a do podcierania - papier ścierny

0

A vector wg ciebie korzysta z magii zamiast dynamicznych tablic?
Skoro u ciebie vector działa lepiej oznacza to tylko jedno - jeszcze nie umiesz posługiwać się dynamicznym przydzielaniem pamięci.
Zalet u vector'a jest tylko dwie:

  • to klasa bardzo dobrze sprawdzona więc z prawdopodobieństwem 99.99% (jak nie większym) nie zawiera błędu.
  • nie trzeba jej pisać, już jest napisana.
0
_13th_Dragon napisał(a):

A vector wg ciebie korzysta z magii zamiast dynamicznych tablic?
Skoro u ciebie vector działa lepiej oznacza to tylko jedno - jeszcze nie umiesz posługiwać się dynamicznym przydzielaniem pamięci.
Zalet u vector'a jest tylko dwie:

  • to klasa bardzo dobrze sprawdzona więc z prawdopodobieństwem 99.99% (jak nie większym) nie zawiera błędu.
  • nie trzeba jej pisać, już jest napisana.

Nie no, oczywiście, że vector korzysta z dynamicznych tablic. Pytanie jest właśnie tego typu, czy w związku z tym są jakieś przeciwskazania (lub praktyczne zastosowania) niekorzystania z tej klasy, gdy potrzebujemy tablicę dynamiczną? Tzn. czy jest jakiś powód, by zrobić:

double* tablica = new double[size];

zamiast:

vector<double> tablica(size);

A drugie pytanie brzmi: jeśli C++ ma taki vector to jak się ma porównanie takiego C# lub Javy, które mają zarządzaną pamięć? Czy vector nie jest rozwiązaniem analogicznym?
Bo moim zdaniem obecnie jedyną wadą C++ (poza kilkoma niedociągnięciami - jak np. dość nieczytelne korzystanie ze wskaźników na metody, które są składnikami klasy, która przechowuje metodę :P) jest brak biblioteki standardowej związanej z tworzeniem okienek :).

1

W Javie masz sprawdzanie indeksów tablicy w każdym przypadku. Nie da się mazać po pamięci dowolnie. Nie ma też arytmetyki wskaźników.

Poza tym vector sam się nie odśmieci, w typowej implementacji C++. Jeżeli zaalokowałeś vector na stercie i przestaje być potrzebny (tzn nie ma na niego wskaźników, oprócz tego służącego do usuwania go) to musisz własnoręcznie go sprzątnąć.

Oczywiście różnic jest znaaaacznie więcej.

3
BeBetter napisał(a):

Pytanie jest właśnie tego typu, czy w związku z tym są jakieś przeciwskazania (lub praktyczne zastosowania) niekorzystania z tej klasy, gdy potrzebujemy tablicę dynamiczną? Tzn. czy jest jakiś powód, by zrobić:

double* tablica = new double[size];

zamiast:

vector<double> tablica(size);

Generalnie ja znam 2, takie powody:

  1. W danym projekcie (z jakiś względów technicznych) nie możesz użyć stla/boosta/eastla/etc.
  2. Twój szef/project manager jest idiotą i wymusza nieużywanie stla/boosta/eastla/etc.

Poza tymi przypadkami wszędzie gdzie możesz zamiast ręcznie zarządzanej, dynamicznej tablicy używaj std::vectora, eastl::vector, czy jakiegoś odpowiednika tego kontenera z innej libki. Podobnie zamiast statycznej tablicy lepiej używaj std::array, czy boost::array.

BeBetter napisał(a):

A drugie pytanie brzmi: jeśli C++ ma taki vector to jak się ma porównanie takiego C# lub Javy, które mają zarządzaną pamięć? Czy vector nie jest rozwiązaniem analogicznym?
Bo moim zdaniem obecnie jedyną wadą C++ (poza kilkoma niedociągnięciami - jak np. dość nieczytelne korzystanie ze wskaźników na metody, które są składnikami klasy, która przechowuje metodę :P) jest brak biblioteki standardowej związanej z tworzeniem okienek :).

std::vector to szablon klasy - kontener. W sensie Twojego pytania std::vector nie jest rozwiązaniem analogicznym do rozwiązań z C#, czy Javy.
A odnośnie wad C++....to radzę Ci się wstrzymać z opinią do czasu, gdy zaczniesz uczyć się idiomów rozwiązujących "specyficzne" dla tego języka problemy, czy też spędzisz x-czasu na rozkminianiu np. reference collapsing. Parafrazując wypowiedź S. Kisielewskiego "C++ to język, w którym bohatersko pokonuje się trudności nieznane w żadnym innym języku programowania".

5

Poza tym vector sam się nie odśmieci, w typowej implementacji C++. Jeżeli zaalokowałeś vector na stercie i przestaje być potrzebny (tzn nie ma na niego wskaźników, oprócz tego służącego do usuwania go) to musisz własnoręcznie go sprzątnąć.

Jak już zmądrzeliśmy na tyle, żeby z vectora skorzystać to nie będziemy go ręcznie usuwać. Po to jest vector i smart pointery, żeby tego nie robić.

0

Dzięki wszystkim za wypowiedzi!
Dla pewności jeszcze zapytam: jeśli wykonam następujący kod:

vector<double>* tablica2D = new vector<double>[Y_size];
for(int i=0; i<Y_size; i++)
   tablica2D[i].resize(X_size);
///...
delete[] tablica2D;

To zwolnię całą pamięć? Pewności nie mam, ale wydaje mi się, że nie - usunę tylko tablicę z vectorami, ale one ciągle gdzieś "tam" będą?
Czyli powinienem zrobić tak przed usunięciem tablicy:

for(int i=0; i<Y_size; i++)
   tablica2D.resize(0);

Zgadza się?
Bo do smart pointerów jeszcze nie doszedłem a chciałem zrobić coś na szybko w 2D ;) -> a korzystanie z vectora vectorów jest trochę bardziej złożone...

1

Generalnie jeżeli tylko masz taką możliwość to używaj std::vector zamiast dynamicznych tablic. Wskaźniki to zło mimo że w C++ na szeroką skale są używane to w dużych zaawansowanych projektach unika się pewnych elementów C++ które są trudne w użyciu / utrzymaniu / utrudniają pisanie / analizowanie kodu np właśnie wskaźniki, wyjątki, dynamiczna alokacja pamięci, wielokrotne dziedziczenie.

3

Czemu nie zrobisz po ludzku:

vector<vector<double> > tablica2D(Y_size,vector<double>(X_size));

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