Dynamiczna tablica, a statyczna

0

Hej ,dobra praktyka jest wyrabianie sobie nawyku używania tablicy dynamicznej ? :)

np .

int*  tablica = new int[rozmiar_tablicy] ;

Umiecie powiedzieć jakie zagrożenia i tym samym korzyść z tego płyną ?

No bo przecież zawsze mogę zrobić też tak;

unsigned int moja_liczba;

cin>>moja_liczba;
int tab[moja_liczba];

1

Co do drugiego zapisu, to formalnie nie można tak robić. Polecam vector i inne z STL
Zagrożenie jest takie, że przy zabawie wskaźnikami możesz łatwiej wywalić program i mieć wycieki pamięci.

0

To co wkleiłeś to nie są tablice dynamiczne. W obu przypadkach rozmiar tablicy jest stały podczas wykonywania programu. Tablica dynamiczna może rosnąć wraz z dodawaniem do niej danych. https://en.wikipedia.org/wiki/Dynamic_array

1

No bo przecież zawsze mogę zrobić też tak;

Nie, nie powinieneś tak robić. Wartość zmiennej "moja_liczba" powinna być określona na etapie kompilacji. U Ciebie działa dzięki temu, że kompilator implementuje rozszerzenie VLA -> https://en.wikipedia.org/wiki/Variable-length_array
Nie każdy kompilator jest taki sam, więc może być problem z przenośnością.

Co do głównego pytania: nie ma jednej odpowiedzi. Wynika to z tego, że w innym przypadku lepiej zastosować zmienną deklarowaną na stosie ("statyczna") a innym razem na stercie (dynamiczna).
Najczęściej szybsza będzie alokacja na stosie, ponieważ alokacja ogranicza się tylko do przesunięcia wskaźnika stosu. Natomiast w przypadku sterty, to już zależy od implementacji. Na przykład alokacja w systemie Windows jest całkiem szybka (dobre zarządzanie pamięcią). Jednak zawsze wolniejsza od stosu.
Sterty powinno się używać do alokacji dużych bloków danych. Stosu do małych podręcznych zmiennych.

0

Widzę ,że do podjęcia decyzji jest potrzebna znajomość działania stosu i sterty.A powiecie jak najbezpieczniej deklarować tablice ?:)

Mam takie pytanie to już czysta ciekawość :) Czy takie zagadnienie porusza się jeszcze na etapie tworzenia dokumentacji aplikacji ? czy dokumentacja powstaje na bieżąco ?:p

0

A powiecie jak najbezpieczniej deklarować tablice

Co masz na myśli pisząc "najbezpieczniej"?

0

no nie wiem ..poprawnie ?:) taki był kontekst tego wątku .

0

A czytałeś mojego posta? Sposób deklarowania zmiennych oraz przydzielania im pamięci powinieneś dobrać do konkretnego przypadku.

0

okej ,dzięki . Widzę że wszystko zależy od wielkości projektu .Dzieki pozdrawiam :)

0

Trollujesz?
Rozmiar projektu nie ma tutaj nic do rzeczy. Chodzi o wolumen danych.

0

Sterty powinno się używać do alokacji dużych bloków danych. Stosu do małych podręcznych zmiennych.

Po tym wpisie tak wywnioskowałem.

Nie ,to nie jest troll, a cały post jest jak najbardziej poważny. Jeśli tak to odebrałaś to nie to miałem na myśli , swoją drogą twoje odp.są dobre :),ale ze tak ujmę stoją na granicy z arogancja - przynajmniej ja tak to odbieram,zwale na ogólno powszechną znieczulice i brak emotikonek.

2
pain368 napisał(a):

jak najbezpieczniej deklarować tablice ?:)

Jak znasz rozmiar w czasie kompilacji -> std::array, jak nie znasz -> std::vector. Nie wiem czy o to Ci chodziło.

0

Alokacje na stosie są szybsze i mniej śmiecą po pamięci, ponieważ używany jest stały obszar pamięci. Dodatkowo alokacja automatycznie znika po wyjściu ze scope jej widoczności.
Minusem jest natomiast ryzyko bufferoverflow(exploity), stack overflow i ogólnie łatwiej o crash. Ogranicza nas również rozmiar alokacji.

Alokacje na stercie nie są ograniczone rozmiarowo(tzn ogranicza nas ram i rodzaj systemu 32, 64 bity), trudniej o exploita w przypadku pisania poza alokacją.
Minusem sterty jest fakt że alokacja jest wolniejsza, mogą prowadzić do fragmentacji pamięci, oraz jej wycieków.

Generalnie, jeżeli jest to bezpieczne i zależy Ci na prędkości/pamięci dodatkowo alokacja jest na krótki czas(widoczność zmiennej) to stosuj alokacje na stosie. W pozostałych sytuacjach sterta.

0
xxx_xx_x napisał(a):

Minusem jest natomiast ryzyko bufferoverflow(exploity), stack overflow i ogólnie łatwiej o crash. Ogranicza nas również rozmiar alokacji.

Są automatyczne mechanizmy, które wywalają przy próbie wyexploitowania przy buffer overflow, trzeba je wyłączyć żeby exploit przeszedł :(
Eh przejebane kiedyś było łatwiej...

0

jak najbezpieczniej deklarować tablice ?:)

Jak znasz rozmiar w czasie kompilacji -> std::array, jak nie znasz -> std::vector. Nie wiem czy o to Ci chodziło.

Hej , wiesz jestem dość krótko w temacie ,ale czasem jak piszę jakąś aplikacje konsolową np.żeby przećwiczyć jakiś algorytm (bo na tym etapie mniej więcej jestem) to ustalam na samym początku kodu rozmiar,ale nie brzmi to tak jak to napisałeś

"w czasie kompilacji".

0

Nie wiem co rozumiesz przez ustalam sobie rozmiar. Jak jest to jakiś define/constexpr to użyj std::array, jak np. wczytujesz od użytkownika - std::vector

0

No na chwilę obecną znaczy to dla mnie tyle co przypisanie po przez cin>> ,lub wpisanie "z miejsca" jakiejś wartości typu INT w miejsce, w którym określa się rozmiar tablicy [] , czyli to co było mi odradzane :D

[edit]
Okej , własnie dorwałem książkę Bjarne Stroustrup i czytam o tym , i chyba czaje :)

1

Wpisanie przez.strumień, a wpisanie stałej w kodzie to dwa różne sposoby. Do pierwszego vector, do drugiego array.

0
pain368 napisał(a):

Hej ,dobra praktyka jest wyrabianie sobie nawyku używania tablicy dynamicznej ? :)

np .

int*  tablica = new int[rozmiar_tablicy] ;

Umiecie powiedzieć jakie zagrożenia i tym samym korzyść z tego płyną ?

No bo przecież zawsze mogę zrobić też tak;

unsigned int moja_liczba;

cin>>moja_liczba;
int tab[moja_liczba];

Pierwszy przypadek jest w zasadzie niezawodny pomijając skrajne przypadki typu: new int[7], i w ramach tymczasowych - lokalnych obliczeń,
w których dane są tylko na moment potrzebne, a potem znikają.

Drugi przypadek stosujemy tylko dla chwilowych danych... roboczych, i niedużych - do 4KB powiedzmy.

0

Drugi przypadek stosujemy tylko dla chwilowych danych... roboczych<

@wil
Drugi przypadek jest niezgodny ze standardem C++.
Wcześniej w wątku poruszono tą kwestię.

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