Rozszerzalność tablicy dynamicznej

0

Witam. Realizuję zadanie z Podstaw programowania, o tematyce dynamicznych tablic. Napotkałem na problem: Rozszerzalność tablicy dynamicznej

Zrozumiałem to aby przesłać tablicę jako oryginał do funkcji i zwiększyć jej rozmiar. W takim wypadku utworzyłem tablice kopia gdzie przekopiowałem wszystkie elementy tablicy, potem dynamicznie przydzieliłem pamięć do swojej oryginalnej tablicy z nowym rozmiarem. i znowu przekopiowałem dane, dodając nowy element.

 
//funkcja dodaje element na koniec tablicy dynamicznej typu int (zadana jako argument)
void DodajNaKoniec( int *tab, int &roz) 
{
    int ostatni = 999; // element ktory dodamy na koniec
    cout << "Dodanie na Koniec liczby: " << ostatni << endl;
    int zwiekszony = roz+1; // nowy  rozmiar tablicy
    int *kopia = new int[zwiekszony]; // bedzie to nasz schowek z liczbami  zanim zwiekszymy rozmiar tablicy

    // kopiowanie elementow
    for(int i=0; i<roz; i++)
        kopia[i] = tab[i];

    kopia[roz] = ostatni; // dodajemy ostatni element

    tab = new int[zwiekszony]; //  Przydzielamy na nowo pamiec z nowym rozmiarem

    // kopiowanie elementow
    for(int i=0; i<zwiekszony; i++)
        tab[i] = kopia[i];

    roz = zwiekszony; // naszy rozmiar teraz staje sie zwiekszonym
    WyswietlTablice(tab, roz);
    delete [] kopia;   // zwalniamy  przydizelona pamiec
}
int main()
{
    int roz = 10;
    int *tab = new int[roz]; // dynamicznie tworzona tablica

    WylosujLiczby(tab, roz);
    DodajNaKoniec(tab, roz);
    WyswietlTablice(tab,roz);
    delete [] tab; // zwalniamy zaalokowana pamiec
    return 0;
}

Problemy

  • 2 razy została przydzielona Pamieć dynamiczna;
  • Przy wyświetleniu tablicy w funkcji widać ostatni element, natomiast po wyjściu z niej nie ma go.

Pytania:

  1. Czy jest jakaś lepsza możliwość zmiany rozmiaru tablicy dynamicznej ?
  2. Dlaczego Przy wywolaniu funkcji WyswietlTablicew mainie nie ma elementu 999 ?
    user image
2
  1. nie zwalniasz starej tablicy
  2. jak chcesz modyfikować wskaźnik, to musisz go przekazać jako ** albo &* *&
  3. zwiększanie o 1 jest nieefektywne.
2
tab = new int[zwiekszony]; //  Przydzielamy na nowo pamiec z nowym rozmiarem

A po co? Zakładając, że przekazałeś tab jako *& tak jak @kaczus radzi, to wystarczy:

delete[] tab;
tab = kopia;
// delete[] kopia  - oczywiscie NIE usuwamy tej tablicy

Żeby nie było wątpliwości, tab = kopia nie kopiuje żadnych danych, po prostu wskazujesz wskaźnikiem tab na ten sam obszar pamięci co wskaźnik kopia.

0

dziękuję dużo mi pomogły wasze odpowiedzi. Jest jeszcze jedna rzecz o którą chcę zapytać. Zrobiłem jak radziliście, ale
// delete[] kopia - oczywiscie NIE usuwamy tej tablicy
mimo to usunąłem z ciekawości. Program w funkcji jak i w mainie wyświetla prawidłowo tablicę.
Co w takim razie popsułem o nie zdaję sobie teraz o tym sprawy ?
W jakim przypadku program mógłby się wysypać przez to ?

void DodajNaKoniec( int *&tab, int &roz) // pracujemy na referencjach
{
    int ostatni = 999; // element ktory dodamy na koniec
    cout << "Dodanie na Koniec liczby: " << ostatni << endl;
    int zwiekszony = roz+1; // nowy  rozmiar tablicy
    int *kopia = new int[zwiekszony]; // bedzie to nasz schowek z liczbami  zanim zwiekszymy rozmiar tablicy

    // kopiowanie elementow
    for(int i=0; i<roz; i++)
        kopia[i] = tab[i];

    kopia[roz] = ostatni; // dodajemy ostatni element
    delete [] tab; // zwalniam stary przydzial na tablice
    tab = kopia; // wskaznik wskazuje teraz na to samo miejsce w pamieci co kopia

    roz = zwiekszony; // naszy rozmiar teraz staje sie zwiekszony
    WyswietlTablice(tab, roz);
    delete [] kopia;   // zwalniamy  przydizelona pamiec
} 
0
darthachill napisał(a):

mimo to usunąłem z ciekawości. Program w funkcji jak i w mainie wyświetla prawidłowo tablicę.

Bo to undefined behaviour, więc raz zadziała, a innym razem się wysypie. Jeden z najgorszych typów błędów.

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