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

Dynamiczna alokacja tablicy struktur

0 głosów
3,117 wizyt
pytanie zadane 24 lipca 2017 w C i C++ przez Dooky Początkujący (480 p.)

Próbuję stworzyć nieskończoną tablicę struktury. Program się kompiluje ale gdy chce wpisać coś do nowej powiększonej tablicy coś crashuje. Mam od razu pytanie czy w prawidłowy sposób przesyłam tablicę struktur do funkcji:

#include <iostream>
using namespace std;

struct notatnik{
int ilosc_dni;
string imie;
};

void zwiekszenie_obydwu_tablic_krok1(notatnik* tablica,int *stary_rozmiar);
void zwiekszenie_obydwu_tablic_krok2(notatnik* tymczasowa_tablica,int nowy_rozmiar);

int main()
{
int rozmiar = 2;
int koniec_wpisywania = 1;
notatnik *tablica = new notatnik[rozmiar];
while (koniec_wpisywania != 0)
{
    for (int i = 0; i < rozmiar ; i++){
    cout<<"rozmiar tablicy:"<<rozmiar<<endl;
    cout<<"imie:  ";
    cin>>tablica[i].imie;
    cout<<"dni: ";
    cin>>tablica[i].ilosc_dni;
    cout<<"Jesli koniec wpisz 0 jeśli nie 1:";
    cin>>koniec_wpisywania;
    if ( i == rozmiar -1 )
    {
        zwiekszenie_obydwu_tablic_krok1(tablica,&rozmiar);
    }
    }
}
delete [] tablica;
}



void zwiekszenie_obydwu_tablic_krok1(notatnik* tablica,int *rozmiar)
{
    int nowy_rozmiar = *rozmiar * 2;
    notatnik *tymczasowa_tablica = new notatnik[nowy_rozmiar];
    for (int i = 0; i < *rozmiar; i++){
        tymczasowa_tablica[i].imie = tablica[i].imie;
        tymczasowa_tablica[i].ilosc_dni = tablica[i].ilosc_dni;
    }
    delete [] tablica;
    *rozmiar *= 2;
    zwiekszenie_obydwu_tablic_krok2(tymczasowa_tablica,nowy_rozmiar);
}

void zwiekszenie_obydwu_tablic_krok2(notatnik* tymczasowa_tablica,int nowy_rozmiar)
{
    notatnik *tablica = new notatnik[nowy_rozmiar];
    for (int i = 0; i < nowy_rozmiar; i++){
        tablica[i].imie = tymczasowa_tablica[i].imie;
        tablica[i].ilosc_dni = tymczasowa_tablica[i].ilosc_dni;
    }
    delete [] tymczasowa_tablica;
}

 

 

1 odpowiedź

+1 głos
odpowiedź 24 lipca 2017 przez PoetaKodu Stary wyjadacz (10,990 p.)
wybrane 24 lipca 2017 przez Dooky
 
Najlepsza

Popatrz co się dzieje w funkcji "zwiekszenie_obydwu_tablic_krok2":
 

void zwiekszenie_obydwu_tablic_krok2(notatnik* tymczasowa_tablica,int nowy_rozmiar)
{
    notatnik *tablica = new notatnik[nowy_rozmiar];
    for (int i = 0; i < nowy_rozmiar; i++)
    {
        tablica[i].imie = tymczasowa_tablica[i].imie;
        tablica[i].ilosc_dni = tymczasowa_tablica[i].ilosc_dni;
    }
    delete [] tymczasowa_tablica;
}

Masz wyciek pamięci, bo tworzysz nową tablicę dynamicznie "tablica", do której tracisz wskaźnik po wyjściu z funkcji. Pamiętaj, że wskaźnik "tablica" w funkcji "zwiekszenie_obydwu_tablic_krok2" to nie to samo co "tablica" w funkcji "main".
W ogóle ten program można lepiej zrobić. Z tego co widzę, chcesz zwiększyć rozmiar tablicy 2x.
Zrób to tak:
 

notatnik* zmienRozmiar(notatnik *tab, int staryRozmiar, int nowyRozmiar);

int main()
{
    notatnik *tablica = new notatnik[rozmiar];

    // kiedy chcesz rozszerzyc tablice
    tablica = zmienRozmiar(tablica, rozmiar, rozmiar*2);
    rozmiar *= 2;
}

notatnik* zmienRozmiar(notatnik *tab, int staryRozmiar, int nowyRozmiar)
{
    notatnik *nowaTablica = new notatnik[nowyRozmiar];
    memcpy(nowaTablica, tab, std::min(staryRozmiar, nowyRozmiar)*sizeof(notatnik));
    delete [] tab;
    return nowaTablica;
}

Ten kod działa tak: masz aktualny rozmiar i tablicę. Kiedy chcesz ją zmniejszyć/zwiększyć, to:
Tworzysz nową tablicę "nowaTablica" o nowym rozmiarze.
Kopiujesz funkcją "memcpy" dane ze starej tablicy - pierwszy argument to docelowa tablica, drugi to źródłowa a trzeci to liczba bajtów do skopiowania (std::min(staryRozmiar, nowyRozmiar) sprawia, że funkcja "zmienRozmiar" poprawnie może również zmniejszyć rozmiar). Ilość bajtów do skopiowania to staryRozmiar * ilość bajtów, która zajmuje struktura "notatnik", a to można uzyskać przez "sizeof(notatnik)". Po tym skopiowaniu danych można usunąć starą tablicę a zwrócić nowy wskaźnik.

komentarz 24 lipca 2017 przez Dooky Początkujący (480 p.)
Dzięki za wytłumaczenie :) Wcześniej nie znałem komendy memcpy. Już działa i o to mi chodziło.
komentarz 24 lipca 2017 przez jpacanowski VIP (101,940 p.)
memcpy() to nie komenda, tylko funkcja... język C/C++ nie posiada komend.
komentarz 25 lipca 2017 przez Dooky Początkujący (480 p.)
Postaram się zapamiętać dzięki.

Podobne pytania

0 głosów
2 odpowiedzi 1,778 wizyt
pytanie zadane 3 lipca 2018 w C i C++ przez qlucha Obywatel (1,790 p.)
0 głosów
2 odpowiedzi 2,160 wizyt
pytanie zadane 24 stycznia 2017 w C i C++ przez spvce Początkujący (260 p.)
0 głosów
1 odpowiedź 572 wizyt

93,742 zapytań

142,678 odpowiedzi

323,297 komentarzy

63,326 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

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...