Problem z vector::emplace_back i znikająca pamięć?
Ostatnio zmodyfikowano 2020-01-05 18:37
Szustarol Temat założony przez niniejszego użytkownika |
Problem z vector::emplace_back i znikająca pamięć? » 2020-01-04 23:06:48 Witam. Napotykam problem podczas implementacji pewnego schematu: #include <iostream> #include <vector> #include <cstdlib>
class child { public: char * data; unsigned size; child() { data =( char * ) malloc( sizeof( char ) * 8 ); size = 8; } ~child() { free( data ); } void resize( unsigned size ) { data =( char * ) realloc( data, size * sizeof( char ) ); this->size = size; } };
class parent { public: child ch; void print() { for( unsigned i = 0; i < ch.size; i++ ) { std::cout << ch.data[ i ]; } std::cout << std::endl; } parent( char dataval ) { ch.resize( 40 ); for( unsigned i = 0; i < 40; i++ ) ch.data[ i ] = dataval; std::cout << "In constructor: " << std::endl; print(); } ~parent() { }; };
int main() { std::vector < parent > par; for( char i = 'a'; i < 'z'; i++ ) { par.emplace_back( i ); std::cout << "Outside constructor: " << std::endl; par.at( par.size() - 1 ).print(); } }
Schemat w pisanym przeze mnie programie jest podobny, ale bardziej skomplikowany, dlatego stworzyłem wypisany powyżej program, który ma za zadanie zademonstrować mój problem, mianowicie w programie nagle dane utworzone w konstruktorze są inne niż dane które są odczytane z klasy jakiś czas później. W przypadku mojego programu dane nie są inne, bo przypuszczalnie program za mało robi w tzw. międzyczasie, ale tak czy inaczej po utworzeniu kilkunastu instancji za pomocą emplace back program się wysypuje. Gdy zastąpie par.emplace_back( i ); std::cout << "Outside constructor: " << std::endl; par.at( par.size() - 1 ).print();
przez parent p; std::cout << "Outside constructor: " << std::endl; p.print();
wszystko działa jak należy i się nie wysypuje - więc problem ewidentnie wynika z użycia wektora. Co robię nie tak? |
|
nanoant20 |
» 2020-01-05 09:33:22 więc problem ewidentnie wynika z użycia wektora. Co robię nie tak? |
z vector'em wszystko o.k. zakomentuj w destruktorze |
|
pekfos |
» 2020-01-05 11:45:21 Brakuje poprawnej implementacji konstruktora kopiującego i operatora przypisania. Odpowiedź powyżej niczego nie naprawia i tylko wprowadza wyciek pamięci. |
|
Szustarol Temat założony przez niniejszego użytkownika |
» 2020-01-05 17:59:21 okej, dzięki @pekfos za wyjaśnienie - rozumiem że taki konstruktor jest potrzebny, ponieważ w pewnym momencie wektor przy emplace back robi kopię obiektu parent, a więc i obiektu child w nim. Mam jednak dylemat - przecież emplace_back z założenia jest funkcją która (chyba) nie powinna nic kopiować i powinna konstruować obiekt bezpośrednio w pamięci wektora- teoretycznie żadne kopiowanie a tym bardziej przypisanie nie powinno być miejsca. Przykład ten dowodzi jednak, że jestem w błędzie - dlaczego tak się dzieje? |
|
pekfos |
» 2020-01-05 18:05:48 emplace_back z założenia jest funkcją która (chyba) nie powinna nic kopiować i powinna konstruować obiekt bezpośrednio w pamięci wektora- teoretycznie żadne kopiowanie a tym bardziej przypisanie nie powinno być miejsca. |
Wektor trzyma elementy w ciągłym obszarze pamięci i jeśli bieżąca pojemność jest zbyt mała, wszystkie elementy są kopiowane / przenoszone w nowe miejsce. Musiałbyś zarezerwować odpowiednio dużo pamięci wywołaniem reserve() żeby tego uniknąć. |
|
Szustarol Temat założony przez niniejszego użytkownika |
» 2020-01-05 18:37:49 No tak, zapomniałem o tym fakcie - mojej uwadze umknęło to, że przecież kilka pierwszych elementów jest pomyślnie umieszczanych. Wszystko jasne, dzięki za pomoc |
|
« 1 » |