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

Zarządzanie pamięcią new i delete

VPS Starter Arubacloud
0 głosów
782 wizyt
pytanie zadane 9 lutego 2019 w C i C++ przez Michał_Warmuz Mądrala (5,830 p.)

Cześć Mam takie zadanie i chciałbym was sie spytać abyscie mi pokazali droge jak zrobić to zadanie a dokladnie aby wpisać dane do tablicy ktora niema szytwno okreslonego rozmiaru 

 

Zadanie:

Zmodyfikuj przykładowy kod tak, aby nowa tablica nie była tworzona za każdym razem, gdy dodawany jest nowy element.

Przyklad:

#include <iostream>


int main()
{
    int * tablica = nullptr, rozmiar = 0;
    std::cout << "Podawaj liczby, 0 konczy wczytywanie.\n";
    
    while( true )
    {
        int liczba;
        std::cin >> liczba;
        
        if( liczba == 0 )
             break;
        
        // Brakuje miejsca, utwórz większą tablicę
        int * nowa = new int[ rozmiar + 1 ];
        
        // Skopiuj dane
        for( int i = 0; i < rozmiar; ++i )
             nowa[ i ] = tablica[ i ];
        
        // Dodaj nową wartość
        nowa[ rozmiar ] = liczba;
        
        // Usuń starą tablicę
        delete[] tablica;
        
        // Zakutalizuj zmienne
        tablica = nowa;
        rozmiar++;
    }
    
    std::cout << "Te same liczby, ale odwrotnie!\n";
    
    for( int i = rozmiar - 1; i >= 0; --i )
         std::cout << tablica[ i ] << ' ';
    
    delete[] tablica;
}

 

komentarz 9 lutego 2019 przez dawid2002 Mądrala (5,190 p.)
Nie wiem czy te rozwiązanie ci się spodoba , ale mógłby twój program po prostu spytać użytkownika ile poda liczb i tą wartość którą poda ustawić jako rozmiar tablicy - tablica. W ten sposób tylko raz dojdzie do alokacji i nie będzie potrzeby zmieniania rozmiaru tej tablicy.

2 odpowiedzi

+3 głosów
odpowiedź 9 lutego 2019 przez gagyn Stary wyjadacz (11,050 p.)
wybrane 10 lutego 2019 przez Michał_Warmuz
 
Najlepsza
Rozwiązań jest kilka:

1. Tworzysz dużą tablicę, która będzie wystarczająca na wszystkie wpisywane liczby.

Jeżeli jednak liczb tych może być naprawdę dużo lub ważne jest oszczędzanie pamięci, to ten sposób odpada. Choć w przypadku zadań algorytmicznych, często nie jest określona ilość pamięci ram lub jest na tyle duża, że można sobie na to pozwolić oraz zyskujemy na czasie (tylko jeden raz alokujemy tablicę).

2. Tak jak już RafalS napisał, możesz zwiększać rozmiary nowych tablic o większą liczbę niż jeden - np. 2/5/10 razy.

Zaletą jest to, że jeżeli będziesz miał mało liczb do wpisania, to mało pamięci będzie używane. Jednak w przypadku np. 100 tys zmiennych w tablicy i tak trochę czasu zajmie tworzenie tych tablic.

3. Możesz również skorzystać z vector, jeżeli polecenie zadania na to pozwala.

Vector działa podobnie do tablic, jednak umożliwia dużo łatwiejsze zarządzanie "tablicą".

Poczytaj: http://www.cplusplus.com/reference/vector/vector/
komentarz 10 lutego 2019 przez Michał_Warmuz Mądrala (5,830 p.)

Czy dobrze zrozumiałem z tym pomnozeniem ? 

Napisałem kod i niby działa czy to o to chodziło ?

#include <iostream>

using namespace std;

int main()
{
    int *tablica = nullptr; int rozmiar = 0;
    int liczba;
    int ilosc_liczb=0;


    while(true) {
         cout << "Podaj liczbe (0 konczy program): ";
         cin>>liczba;

         if(liczba == 0) break;
         else ilosc_liczb++;

         if(rozmiar < ilosc_liczb)
            ilosc_liczb*=2;

         int *nowa = new int [ilosc_liczb];

         for(int i=0; i<rozmiar; i++) {
            nowa[i] = tablica[i];
         }

         nowa[rozmiar] = liczba;

         delete [] tablica;

         tablica = nowa;
         rozmiar++;
    }

    for(int i=0; i<rozmiar; i++) {
        cout << tablica[i] << endl;
    }
    return 0;
}

 

komentarz 11 lutego 2019 przez gagyn Stary wyjadacz (11,050 p.)
edycja 11 lutego 2019 przez gagyn

Nie do końca, ponieważ wciąż co każdy krok pętli tworzysz nową tablicę. Powinieneś tworzyć nową tablicę tylko w momencie kiedy rozmiar jest mniejszy od ilości liczb.

 

ilosc_liczb++;
if(rozmiar < ilosc_liczb)
{
      rozmiar *= 2;
      int *nowa = new int [rozmiar];
      for(int i=0; i < ilosc_liczb - 1; i++) {
            nowa[i] = tablica[i];
      }
      delete [] tablica;
      tablica = nowa;
}

tablica[ilosc_liczb - 1] = liczba;

 

komentarz 11 lutego 2019 przez gagyn Stary wyjadacz (11,050 p.)
To powinno być wewnątrz pętli while. Tworzenie nowej tablicy i kopiowanie powinno następować tylko wtedy, kiedy rozmiar jest mniejszy od liczby liczb, w przeciwnym wypadku jedynie dodaje do tablicy nową liczbę. W każdym przypadku na początku pętli inkrementuje zmienną ilosc_liczb.
komentarz 11 lutego 2019 przez Michał_Warmuz Mądrala (5,830 p.)
#include <iostream>

using namespace std;

int main()
{
    int *tablica = nullptr; int rozmiar = 0;
    int liczba;
    int ilosc_liczb=0;


    while(true) {
         cout << "Podaj liczbe (0 konczy program): ";
         cin>>liczba;

         if(liczba == 0) break;
            ilosc_liczb++;
            if(rozmiar < ilosc_liczb)
            {
                  ilosc_liczb *= 2;
                  int *nowa = new int [ilosc_liczb];
                  for(int i=0; i < rozmiar; i++) {
                        nowa[i] = tablica[i];
                  }
                  delete [] tablica;
                  tablica = nowa;
            }

            tablica[rozmiar] = liczba;
            rozmiar++;
    }

    for(int i=0; i<rozmiar; i++) {
        cout << tablica[i] << endl;
    }
    return 0;
}

Tak to ma wyglądać ?

komentarz 11 lutego 2019 przez gagyn Stary wyjadacz (11,050 p.)
Przeczytałeś mój komentarz?
komentarz 11 lutego 2019 przez Michał_Warmuz Mądrala (5,830 p.)
Tak i zmodyfikowałem swój program. a pytam tak dla pewności bo ten kod ktory wstawiłes nie działa troche teraz siedziała po zmieniałem co pisałeś i teraz działa i tylko chce sie upewnić :)
komentarz 11 lutego 2019 przez gagyn Stary wyjadacz (11,050 p.)

Mój błąd. Dodałem jeden warunek i teraz działa.

	while (true) {

		cout << "Podaj liczbe (0 konczy program): ";
		cin >> liczba;

		if (liczba == 0)
			break;
		
		ilosc_liczb++;
		if (rozmiar < ilosc_liczb)
		{
			if (rozmiar == 0)
				rozmiar++;
			else
				rozmiar *= 2;

			int *nowa = new int[rozmiar];
			for (int i = 0; i < ilosc_liczb - 1; i++) {
				nowa[i] = tablica[i];
			}
			delete[] tablica;
			tablica = nowa;
		}

		tablica[ilosc_liczb - 1] = liczba;

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

 

komentarz 11 lutego 2019 przez gagyn Stary wyjadacz (11,050 p.)
Problem polegał na tym, że zmienna rozmiar na początku jest równa zero, więc pomnożona przez 2, cały czas daje 0.
+1 głos
odpowiedź 9 lutego 2019 przez RafalS VIP (122,820 p.)
Zwiększaj rozmiar nie o +1 tylko *2. Jedna zmienna to prawdziwy rozmiar zaalokowanej tablicy, a druga to ile elementów jest w tej tablicy zapisanych. Dopóki starcza miejsca  (ilosc zapisanych  < rozmiar zaalokowanej) to normalnie wpisujesz w przeciwnym wypadku zwiekszasz rozmiar razy 2 i przepisujesz elementy.
komentarz 11 lutego 2019 przez Michał_Warmuz Mądrala (5,830 p.)

Tak to ma wyglądać ?

#include <iostream>

using namespace std;

int main()
{
    int *tablica = nullptr; int rozmiar = 0;
    int liczba;
    int ilosc_liczb=0;


    while(true) {
         cout << "Podaj liczbe (0 konczy program): ";
         cin>>liczba;

         if(liczba == 0) break;
            ilosc_liczb++;
            if(rozmiar < ilosc_liczb)
            {
                  ilosc_liczb *= 2;
                  int *nowa = new int [ilosc_liczb];
                  for(int i=0; i < rozmiar; i++) {
                        nowa[i] = tablica[i];
                  }
                  delete [] tablica;
                  tablica = nowa;
            }

            tablica[rozmiar] = liczba;
            rozmiar++;
    }

    for(int i=0; i<rozmiar; i++) {
        cout << tablica[i] << endl;
    }
    return 0;
}

 

Podobne pytania

0 głosów
1 odpowiedź 139 wizyt
0 głosów
1 odpowiedź 257 wizyt
0 głosów
3 odpowiedzi 575 wizyt

92,453 zapytań

141,262 odpowiedzi

319,086 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...