• 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

0 głosów
73 wizyt
pytanie zadane 9 lutego w C i C++ przez Michał_Warmuz Gaduła (4,140 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 przez dawid2002 Obywatel (1,360 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

+1 głos
odpowiedź 9 lutego przez gagyn Gaduła (3,250 p.)
wybrane 10 lutego 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 przez Michał_Warmuz Gaduła (4,140 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 przez gagyn Gaduła (3,250 p.)
edycja 11 lutego 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 przez gagyn Gaduła (3,250 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 przez Michał_Warmuz Gaduła (4,140 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 przez gagyn Gaduła (3,250 p.)
Przeczytałeś mój komentarz?
komentarz 11 lutego przez Michał_Warmuz Gaduła (4,140 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 przez gagyn Gaduła (3,250 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 przez gagyn Gaduła (3,250 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 przez RafalS VIP (102,770 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 przez Michał_Warmuz Gaduła (4,140 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ź 92 wizyt
0 głosów
3 odpowiedzi 264 wizyt
+1 głos
1 odpowiedź 760 wizyt
Porady nie od parady
Pytania na temat serwisu SPOJ należy zadawać z odpowiednią kategorią dotyczącą tej strony.SPOJ

60,244 zapytań

105,928 odpowiedzi

220,065 komentarzy

32,445 pasjonatów

Przeglądających: 166
Pasjonatów: 3 Gości: 163

Motyw:

Akcja Pajacyk

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

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...