Vector: adresy elementów

0

męczę się z tym parę godzin i nie mam pojęcia co robię źle... może ktoś zauważy, gdzie mam błąd.

mam sobie klasę:

CKlasa1

oraz klasę

CKlasa2

ta klasa ma w sobie vector:

vector<CKlasa1 *> klasy1;

mam sobie funkcję:

void WczytajKlasy1ZPliku(vector<CKlasa1> *kl1s)

która to wczytuje dane z pliku i na tej podstawie tworzy obiekty typu Klasa1 i zapisuje je do vectora kl1s, oraz niektór adresy elementów typu CKlasa1 zapisuje do obiektu typu CKlasa2 (dokładnie do vectora CKlasa2::klasy1), po to, by później się odwoływać do tych elementów.

void WczytajKlasy1ZPliku(vector<CKlasa1> *kl1s, CKlasa2 *kl2)
{
    for (int i=0; i<iletychelementow; ++i)
    {
        CKlasa1 tmp () ;
        //wczytywanie
        kl1s->push_back(tmp) ;
        if(warunek)
        {
            kl2->klasy1.push_back(CKlasa1 *adr1 = &(*kl1s)[kl1s->size()-1]) ;  //adres1
            printf("adr1 = %p\n",adr1) ;
        }
    }

    //no i mi nie działa. dlatego wypisałem sobie adresy:
    for (int i=0; i<kl1s->size(); ++i)
    {
        CKlasa1 *adr2 = &(*kl1s)[i] ;
        printf("adr2 = %p\n",adr2) ;
    }
}

chodzi o to, że adresy adr1 i adr2 różnią się i to mi powoduje później segmentation fault podczas działania programu.

pewnie to jakiś szkolny błąd, ale za chiny nie mogę tego znaleźć....

0

Vector działa tak, że rezerwuje sobie trochę pamięci i trzyma tam swoje elementy. Jeśli tej pamięci mu zabraknie przy kolejnym push_back, to w innym miejscu rezerwuje sobie więcej pamięci i kopiuje w nie wszystkie dodane do tej pory elementy. Elementy te zmieniają więc swój adres, a stara pamięć jest zwalniana. W tym momencie wektor kl2->klasy1 będzie zawierał adresy elementów, które już nie są poprawne.

0

Może w kl2 zapisuj index elementu w wektorze, a nie wskaźnik?

Ewentualnie użyj listy.

0
void WczytajKlasy1ZPliku(vector<CKlasa1> *kl1s, CKlasa2 *kl2)
{
    kl1s->resize(iletychelementow /*+kl1s->count() */); // nie wiem co chcesz zrobić

    for (int i=0; i<kl1s.count(); ++i)
    {
        if(warunek) // domyślam się że ten warunek u ciebie jest bardziej sensowny
        {
            CKlasa1 *adr1 = &kl1s->at(i);
            kl2->klasy1.push_back(adr1) ;  //adres1
            // printf("adr1 = %p\n",adr1) ;
        }
    }
}

Czemu tak? Bo nie masz gwarancji, że w czasie dodawania elementu pamięć nie będzie reallokowana (bo nie da się jej powiększyć).
Możesz też spróbować użyć std::reserve, by zawczasu zarezerwować wymaganą pamięć na obsługę większej ilości elementów.

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