zolty13 Temat założony przez niniejszego użytkownika |
problem z destruktorem » 2017-04-19 23:09:23 Hejka mam taki problem. Klasa posiada 2 wektory które trzymają inne obiekty. Wszystko działa tylko problem pojawia się na koniec programu, gdy wywoływane są destruktory. Ponieżej konstruktor destruktor i metoda napełniająca wektory. Debuger zatrzymuje się na delete. Uzywam dynamicznej alokacji oczywiście, bo przy normalnym tworzeniu obiekty znikną gdy wyjde z metody.(sa lokalne) THREAD to moja wlasna klasa, która korzysta z biblioteki WinnT i windows.h Najsmieszniejsze jest to ze gdy korzystam z Wektorow które przechowują wskaźniki zamiast obiektow to wszystko działa. (oczywiście implikuje to pare zmian w kodzie) ThreadsSupport::ThreadsSupport( Heap & heap ) : myHeap( heap ) , threadsVec() , handlesEventsVec() { }
ThreadsSupport::~ThreadsSupport() { while( threadsVec.size() > 0 ) { Thread * t = &( threadsVec[ threadsVec.size() - 1 ] ); threadsVec.pop_back(); delete t; } while( handlesEventsVec.size() > 0 ) { HANDLE * h = &( handlesEventsVec[ handlesEventsVec.size() - 1 ] ); handlesEventsVec.pop_back(); delete h; } }
void ThreadsSupport::createThreads( int key, int n = 2 ) { for( int i = 1; i <= n; i++ ) { HANDLE * h = new HANDLE( CreateEvent( NULL, FALSE, FALSE, NULL ) ); handlesEventsVec.push_back( * h ); Thread * t = new Thread( key, i, myHeap, * h ); threadsVec.push_back( * t ); } }
tu definicja klasy class ThreadsSupport { public: ThreadsSupport( Heap & ); ~ThreadsSupport(); void createThreads( int key, int n ); int getIndexByThreads( int ); private: vector < Thread > threadsVec; vector < HANDLE > handlesEventsVec; Heap & myHeap; }; [ code ] |
|
mokrowski |
» 2017-04-20 00:02:52 Wiesz, semantyki wątków MS WIndows nie znam. Dość że zerknął bym na zobowiązanie czy (i jak) obiekty są przekazywane do wątku. Czy przez kopię czy .... inaczej (dla MS Windows). Już w innym zapytaniu ktoś się chciał dowiedzieć. Masz powód by "biczować się wątkami MS Windows" jeśli od C++11 są przenośne? W C++11 jest jawne zobowiązanie że argumenty do wątków trafiają zawsze przez kopię. Tam jeśli chcesz przekazać prawdziwą referencję owijasz ją w std::ref(...). |
|
zolty13 Temat założony przez niniejszego użytkownika |
» 2017-04-20 00:05:10 okey no przekazuje ale jakby to powiedzieć klasa Thread to tylko taka obudowa i generalnie ona wywoluje watek i w momencie gdy te destruktory dzialaja żaden watek już nie działa. I problem jest z ta obudowa o co chodzi z tymi wskaźnikami czy cos :/ to w okienku: ComputerArchitecture2.exe has triggered a breakpoint. a to w konsoli debugowania HEAP[ComputerArchitecture2.exe]: Invalid address specified to RtlValidateHeap( 00F20000, 00F30AB0 ) ComputerArchitecture2.exe has triggered a breakpoint. EDIT Czy może to być wina tego ze najpierw usunal(może) się automatycznie wektor a potem dopiero się probuje dobrac do jego składowych? rownie dobrze mogę dac kod z intami i dalej cos jest nie tak #pragma once #include <vector>
class ThreadsSupport { public: ThreadsSupport(); ~ThreadsSupport(); void create( int key, int n ); private: std::vector < int > intVec; };
#include "stdafx.h" #include "ThreadsSupport.h"
ThreadsSupport::ThreadsSupport() : intVec() { }
ThreadsSupport::~ThreadsSupport() { while( intVec.size() > 0 ) { int * t = &( intVec[ intVec.size() - 1 ] ); intVec.pop_back(); delete t; } }
void ThreadsSupport::create( int key, int n = 2 ) { for( int i = 1; i <= n; i++ ) { int * t = new int( 100 ); intVec.push_back( * t ); } }
#include "stdafx.h" #include <Windows.h> #include "ThreadsSupport.h"
int main() { ThreadsSupport t = ThreadsSupport(); t.create( 5, 2 ); system( "PAUSE" ); system( "PAUSE" ); return 0; }
|
|
michal11 |
» 2017-04-20 07:31:55 wow, po pierwsze masz wyciek, najpierw tworzysz dynamicznie obiekt, później kopiujesz go do vectora, ale oryginalnego obiektu nie usuwasz. W destruktorze próbujesz usunąć obiekt o automatycznym czasie życia (dlatego dostajesz wyjątek podczas runtime'u). Zdecyduj się na jedno rozwiązanie albo trzymasz obiekty w vectorze (nie musisz wtedy dynamicznie ich alokować), albo trzymasz wskaźniki (najlepiej smart pointery, nie musisz się wtedy przejmować destruktorem) i wtedy dynamiczna alokacja ma sens. |
|
mateczek |
» 2017-04-20 07:41:47 int * t = new int( 100 ); intVec.push_back( * t );
intVec.push_back( 100 )
|
|
michal11 |
» 2017-04-20 10:22:11 W destruktorze próbujesz usunąć obiekt o automatycznym czasie życia (dlatego dostajesz wyjątek podczas runtime'u)
|
nie ma znaczenia czy jest to klasa, int czy jeszcze cokolwiek innego. |
|
zolty13 Temat założony przez niniejszego użytkownika |
» 2017-04-20 13:07:06 dzięki już do tego doszedłem wnocy dzisiaj pytanie tylko jak to zrobić żeby mieć wektor obiektow i mieć tam oryginaly stworzone w tej metodzie? Wektora referencji się nie da zrobić niestety z tego co wiem. |
|
Monika90 |
» 2017-04-20 14:38:11 Może zacznijmy od czegoś innego. Dlaczego masz dwa kontenery? Jeżeli na każdy obiekt Thread przypada jeden event, to może powinny być razem? Np. uchwyt do eventu powinien być składową klasy Thread, albo mogą być razem w strukturze struct X { HANDLE event; Thread thread; };
A po drugie, co jest w klasie Thread i w jaki sposób chcesz tego wszystkiego używać? Bez tych informacji nie wiadomo co ci zarekomendować. Może klasa Thread zawiera składowe których nie można kopiować? Wtedy musiałbyś użyć wektora wskaźników, albo std::list. Jeżeli ta klasa reprezentuje wątek, to oczywiście kopiowanie wątków jest operacją nonsensowną, zamiast tego można je przenosić (chodzi o move-assignment i move-construction). |
|
« 1 » |