Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Lekcja 44 - zarządzanie pamięcią new i delete.

Ostatnio zmodyfikowano 2018-03-02 19:27
Autor Wiadomość
marcinpro
Temat założony przez niniejszego użytkownika
Lekcja 44 - zarządzanie pamięcią new i delete.
» 2018-02-25 17:17:14
Witam przerabiam lekcje 44 i było za zadanie "Zmodyfikuj przykładowy kod tak, aby nowa tablica nie była tworzona za każdym razem, gdy dodawany jest nowy element."

Zrobiłem program i działa, ale nie mam pewności, że jest dobrze zrobiony.

C/C++
#include <iostream>

using namespace std;


int main()
{
   
    int indeks = 0;
    int * tab = new int[ 100 ];
    cout << "Podawaj liczby, 0 konczy wczytywanie.\n";
   
    while( true )
    {
       
        int liczba = 0;
        cin >> liczba;
       
        if( liczba == 0 )
             break;
       
        tab[ indeks ] = liczba;
       
        indeks++;
       
       
    }
   
    for( int i = indeks - 1; i >= 0; --i )
         cout << tab[ i ] << ' ';
   
    delete[] tab;
   
}
P-169610
YooSy
» 2018-02-25 17:28:19
Nie jest zgodny z treścią zadania.
Nie masz zabezpieczenia przed wyjściem poza tablicę,
oraz nie ma powiększania tablicy jeśli obecna jest za mała.
W zadaniu należy zapewnić powiększanie tablicy o więcej niż jeden element,
aby zyskać na wydajności.
P-169611
marcinpro
Temat założony przez niniejszego użytkownika
» 2018-02-26 19:05:41
Czyli ja mam tworzyć nową tablicę, ale np co 5 elementów, a nie co jeden?
P-169625
YooSy
» 2018-02-26 19:19:46
Optymalnie będzie podwoić rozmiar.
P-169626
marcinpro
Temat założony przez niniejszego użytkownika
» 2018-02-26 19:56:23
Ok, zrobiłem coś takiego.

C/C++
#include <iostream>

using namespace std;


int main()
{
   
    int indeks = 0;
    int rozmiartab = 1;
    int iloscliczb = 0;
    int * tab = nullptr;
    cout << "Podawaj liczby, 0 konczy wczytywanie.\n";
   
    while( true )
    {
       
        int liczba = 0;
        cin >> liczba;
       
        if( liczba == 0 )
             break;
        else
             iloscliczb++;
       
        if( iloscliczb >= rozmiartab )
        {
            rozmiartab = rozmiartab * 2;
           
            int * nowa = new int[ rozmiartab ]; // tworzenie nowej tablicy
           
            for( int i = 0; i < indeks; ++i ) // kopiowanie danych
                 nowa[ i ] = tab[ i ];
           
            nowa[ indeks ] = liczba; // dodanie nowej liczby do tablicy
           
            delete[] tab;
           
            tab = nowa;
        }
        else
        {
            tab[ indeks ] = liczba;
        }
       
        indeks++;
       
    }
   
    for( int i = indeks - 1; i >= 0; --i )
         cout << tab[ i ] << ' ';
   
}
P-169627
YooSy
» 2018-02-26 22:02:00
Trochę przekombinowana instrukcja warunkowa w pętli. Wystarczy:
C/C++
if( iloscliczb >= rozmiartab )
{
    rozmiartab = rozmiartab * 2;
   
    int * nowa = new int[ rozmiartab ]; // tworzenie nowej tablicy
   
    for( int i = 0; i < indeks; ++i ) // kopiowanie danych
         nowa[ i ] = tab[ i ];
   
    //nowa[indeks] = liczba; // dodanie nowej liczby do tablicy
   
    delete[] tab;
   
    tab = nowa;
}
tab[ indeks ] = liczba;
Wstawienie nowej wartości wykonywane było w obu gałęziach instrukcji warunkowej (niepotrzebnie),
przecież wychodzi na to, że dodajesz do tablicy w każdym obiegu pętli, więc można zrobić to po
ewentualnym rozszerzeniu rozmiaru tablicy.

Jeszcze lepiej byłoby podzielić kod na funkcje.
P-169636
marcinpro
Temat założony przez niniejszego użytkownika
» 2018-03-02 10:16:25
Ok, poprawiłem kod. Dodałem funkcje do wypisywania. Bo dodawanie liczby z funkcji nie ma sensu bo więcej kodu, jak i sprawdzanie czy jest miejsce itp.

C/C++
#include <iostream>

using namespace std;

void wypisz( int iloscliczb, int tab[], int rozmiartab )

{
    cout << "Liczby podane do tablicy wypisane odwrotnie: ";
    for( int i = iloscliczb - 1; i >= 0; --i )
         cout << tab[ i ] << ", ";
   
    cout << endl << "Rozmiar tablicy:" << rozmiartab << endl;
}


int main()
{
    int liczba = 0;
    int indeks = 0;
    int rozmiartab = 1;
    int iloscliczb = 0;
    int * tab = nullptr;
    cout << "Podawaj liczby, 0 konczy wczytywanie.\n";
   
    while( true )
    {
       
        int liczba = 0;
        cin >> liczba;
       
        if( liczba == 0 )
             break;
        else
             iloscliczb++;
       
        if( iloscliczb >= rozmiartab )
        {
            rozmiartab = rozmiartab * 2;
           
            int * nowa = new int[ rozmiartab ]; // tworzenie nowej tablicy
           
            for( int i = 0; i < indeks; ++i ) // kopiowanie danych
                 nowa[ i ] = tab[ i ];
           
           
            delete[] tab;
            tab = nowa;
        }
        tab[ indeks ] = liczba;
        indeks++;
       
    }
   
    wypisz( iloscliczb, tab, rozmiartab );
   
    return 0;
}
P-169678
YooSy
» 2018-03-02 10:28:58
Dodaj jeszcze funkcję, która rozszerzy tablicę.
Niech przyjmie jako argument obecną tablicę i adres rozmiaru tablicy.
C/C++
int * rozszerz_tablice( int * stara_tablica, int * rozmiar ) {
    int * nowa_tablica = new int[ rozmiar * 2 ];
    // kopiowanie zawartości starej tablicy do nowej
    rozmiar *= 2;
    delete[] stara_talica;
    return nowa_tablica;
}
 i użyć jest w funkcji głównej. Znacznie uprości to kod.

Można jeszcze dopisać funkcję kopiującą tablicę i dodać w niej zabezpieczenie przed nieprawidłowym kopiowaniem.
P-169679
« 1 » 2
  Strona 1 z 2 Następna strona