• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dynamiczne alokowanie pamięci

Object Storage Arubacloud
+1 głos
272 wizyt
pytanie zadane 5 kwietnia 2021 w C i C++ przez Dawidziu Bywalec (2,610 p.)
Czy mógłby mi ktoś wytłumaczyć, jak działa to dynamiczne alokowanie pamięci z użyciem operatora new, bo oglądam 10 odcinek kursu c++ i zupełnie nie rozumiem na jakiej zasadzie to działa i o co tutaj tak właściwie chodai.

2 odpowiedzi

+2 głosów
odpowiedź 5 kwietnia 2021 przez galezia Nowicjusz (180 p.)
W przypadku tablic, dynamiczne alokowanie pamięci pozwala ci na stworzenie tablicy z zmienną liczbą elementów. Normalnie tworząc tablice od razu program musi wiedzieć ile ma miejsc;

int tab[10]- to jest dobrze                  int tab[a]- tu wyskoczy bład

ale ten błąd znika jeśli użyjesz wskaźników z dynamiczną alokacją pamięci czyli;

int *wsk= new int[10];                      int *wsk= new int[a];

Jeśli chodzi o ten proces to z mojego doświadczenia (a nie jest ono duże) stosuje się w trzech przypadkach:

- jeśli chcemy żeby tablica miała zmienny rozmiar czyli to co było powyżej;

- jeśli chcemy zaoszczędzić pamięć. Dynamiczną alokacje można również używać na bardziej złożonych obiektach niż tablice. Dzięki temu na bieżąco można tworzyć obiekty gdy są nam potrzebne i usuwać gdy już są bezużyteczne. Dzięki czemu możemy zwiększyć wydajność programu i zmniejszyć zapotrzebowanie na pamięć.

- ostatnio dotyczy poliformizmu i tego ze jeden wskaźnik może nam służyć do tworzenia różnych rodzajów obiektów.

Patrząc na odcinek na którym jesteś najważniejsze są dla ciebie dwa pierwsze punkty. Dzięki dynamicznej alokacji możesz zrobic tablice ze zmienną liczbą elementów a później ją usunąć i stworzyć kolejną. Jedyną wadą jaką widzę to mała przejrzystość takiego procesu bo po dynamicznej tablicy można ruszac sie jedynie za pomocą wskaźnika. Na dole daje ci mały przykłąd bo wydaje mi sie ze na przykładach jest najłatwiej zrozumiec.

 

_____________________________________________________________

int a

std::cout<<"podaj liczbe pracownikow"<<std::endl;

std::cin>>a;

int wsk=new int[a];

std::cout<<"podaj ile zarabia pierwsza osoba"<<std::endl;

std::cin>>a;

*wsk=a;

std::cout<<"podaj ile zarabia osoba druga i trzecia osoba<<std::endl;

std::cin>>a;

*(wsk+1)=a;

*(wsk+2)=a;

std::cout<<"teraz wyswietlam wszystkich"<<std::endl

for(int i=0;i<3;i++)

{   std::cout<<*(wsk+0)<<std::endl;

}

std::cout<<"powyswietleniu usuwam cała tablice"<<std::endl

delete wsk;

std::cout<<"teraz mozna powtorzyc cały proces ponownie"<<std::endl
komentarz 5 kwietnia 2021 przez tkz Nałogowiec (42,000 p.)

- jeśli chcemy zaoszczędzić pamięć. Dynamiczną alokacje można również używać na bardziej złożonych obiektach niż tablice. Dzięki temu na bieżąco można tworzyć obiekty gdy są nam potrzebne i usuwać gdy już są bezużyteczne. Dzięki czemu możemy zwiększyć wydajność programu i zmniejszyć zapotrzebowanie na pamięć.

To nie jest prawda. 

Na początku warto wiedzieć, że jako programiści C++ mamy dostęp do dwóch rodzajów pamięci. Stos i sterta. Stos służy do alokacji statycznej, czyli bez new(oczywiście obiekty mogą używać new wewnątrz, na przykład: string, vector z standardowej biblioteki). Sterta jest miejscem gdzie odkładają się rzeczy zaalokowane dynamicznie. 

Jeżeli do utworzenia(nie działania na nim, wykluczam gromadzenie danych) obiektu potrzebujesz użyć alokacji dynamicznej, prawdopodobnie zrobiłeś duży błąd przy projektowaniu architektury. Abstrahując, że taki obiekt powinien być rozbity na mniejsze funkcjonalności. 

Tworzeniem obiektu zajmuje się konstruktor, a niszczeniem destruktor. Alokacja i dealokacja nie jest tutaj potrzebna. 

Używanie pamięci na stercie nie wpływa na wydajność. Przynajmniej nie na architekturze 64 bitowej. Na 32 może i tak, ale w negatywny sposób. Obstawiam, ze mogłyby się pojawić problemy z przestrzenią adresową. Ale nie jestem pewny. 

Zapotrzebowanie na pamięć będzie tako samo. Alokacja dynamiczna kompletnie nie wpływa na zmniejszenie zapotrzebowania. No bo jak?

Kod jest błędny.

1
komentarz 5 kwietnia 2021 przez Oscar Nałogowiec (29,290 p.)
O ile pamiętam, to allokacja na stosie to allokacja automatyczna, statyczna to obiekty istniejące jeszcze przed uruchomieniem main(), zadeklarowane poza blokami kodu lub ze słówkiem static.
1
komentarz 5 kwietnia 2021 przez tkz Nałogowiec (42,000 p.)
Racja, mój błąd. Powinno być automatyczna. Alokacja statyczna i tak trafia na stertę.
komentarz 6 kwietnia 2021 przez j23 Mędrzec (194,920 p.)
No nie wiem. Zmienne statyczne tworzone są w segmencie BSS - w specjalnym bloku pamięci przeznaczonym na wspomniane zmienne i stałe.
komentarz 6 kwietnia 2021 przez tkz Nałogowiec (42,000 p.)
Drugi błąd. Racja. Kompletnie zapomniałem o tych sekcjach... https://en.wikipedia.org/wiki/Data_segment
komentarz 6 kwietnia 2021 przez Oscar Nałogowiec (29,290 p.)

@j23,
 BSS albo DATA - zależy czy zainicjowane, czy nie. BSS jest zerowana, DATA to różnie, w normalnych komputerach jest wczytywana z pliku razem z kodem. A np. w embedded jest kopiowana z ROMu.

komentarz 6 kwietnia 2021 przez Dawidziu Bywalec (2,610 p.)

Teraz wiem mniej więcej na jakiej zasadzie to działa, ale po tych komentarzach to zupełnie nic nie rozumiemsad

komentarz 6 kwietnia 2021 przez j23 Mędrzec (194,920 p.)

@Oscar, fakt, zapomniałem o segmencie .data

@Dawidziu, to, o czym pisaliśmy, ma niewiele wspólnego z dynamiczną alokacja pamięci, więc traktuj to jako ciekawostkę ;)

0 głosów
odpowiedź 5 kwietnia 2021 przez mkarolm Początkujący (290 p.)
W trakcie działania podajemy programowi informacje jak dużo pamięci potrzebujemy - np. wczytując z klawiatury ilość elementów tablicy.

Program w trakcie działania zwraca się do systemu operacyjnego o dostęp do takiej ilości pamięci jaka jest potrzebna do przechowania "x" ilości elementów tablicy (oczywiście tablica jest tu tylko przykładem), a system po swojemu znajduje taką pamięć i przydziela ją naszemu programowi.

My w odpowiedzi dostajemy adres w pamięci, gdzie system znalazł odpowiednią ilość pamięci - dlatego adres ten od razu przypisujemy do jakiegoś wskaźnika - w innym wypadku bezpowrotnie by nam to przepadło.
komentarz 6 kwietnia 2021 przez Dawidziu Bywalec (2,610 p.)

Czyli jak dajmy na to utworzę tablicę na wskaźniku, zapisując to w taki sposób:

int a;

int *wskaznik;

cin >> a;

wskaznik = new int [ a ];

Załóżmy, że podałem jako a 5, to czy teraz mogę tej tablicy używać jak normalnej, np. w taki sposób:

*wskaznik [ 3 ] = 2;

cin << *wskaznik [ 1 ];

?

komentarz 6 kwietnia 2021 przez mkarolm Początkujący (290 p.)

Tablicę w ten sposób utworzoną możesz obsługiwać na dwa sposoby, standardowy, który napisałeś - ale bez tej gwiazdki

wskaznik[0] = 5;
cin << wskaznik[1];

Albo drugi z zastosowaniem arytmetyki wskaźników - wiedząc, że dodając do wskaźnika 1 przesuwamy go na kolejny element możemy zrobić pętlę, np. w taki sposób

  for (int i = 0; i < a; i++)
  {
      *wskaznik = i;
      wskaznik++;
  }

  wskaznik -= n; // Trzeba pamietac, ze wskaznik po petli wskazuje na ostatni element


  for (int i = 0; i < a; i++)
  {
      cout << *wskaznik << endl;
      wskaznik++;
  }

Podobne pytania

0 głosów
0 odpowiedzi 138 wizyt
pytanie zadane 18 września 2020 w C i C++ przez RobcioXXL Użytkownik (710 p.)
0 głosów
1 odpowiedź 262 wizyt
0 głosów
2 odpowiedzi 155 wizyt
pytanie zadane 30 listopada 2016 w C i C++ przez qwerty Początkujący (380 p.)

92,550 zapytań

141,392 odpowiedzi

319,520 komentarzy

61,935 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...