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

Dynamiczna alokacja tablicy struktur

Object Storage Arubacloud
0 głosów
2,743 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 916 wizyt
pytanie zadane 3 lipca 2018 w C i C++ przez qlucha Obywatel (1,790 p.)
0 głosów
2 odpowiedzi 1,079 wizyt
pytanie zadane 24 stycznia 2017 w C i C++ przez spvce Początkujący (260 p.)
0 głosów
1 odpowiedź 439 wizyt

92,573 zapytań

141,423 odpowiedzi

319,648 komentarzy

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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...