Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

problem z destruktorem

Ostatnio zmodyfikowano 2017-04-20 14:38
Autor Wiadomość
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)
C/C++
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
C/C++
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 ]
P-160287
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(...).
P-160288
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


C/C++
#pragma once
#include <vector>

class ThreadsSupport
{
public:
    ThreadsSupport();
    ~ThreadsSupport();
    void create( int key, int n );
private:
    std::vector < int > intVec;
};

C/C++
#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++ )
    {
        //HANDLE * h = new HANDLE(CreateEvent(NULL, FALSE, FALSE, NULL));
        //handlesEventsVec.push_back(*h);
        int * t = new int( 100 );
        intVec.push_back( * t );
    }
}


C/C++
// destruktorTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>
#include "ThreadsSupport.h"

int main()
{
    ThreadsSupport t = ThreadsSupport();
    t.create( 5, 2 );
   
    system( "PAUSE" );
    //t.~ThreadsSupport();
    system( "PAUSE" );
    return 0;
}
P-160289
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.
P-160292
mateczek
» 2017-04-20 07:41:47
C/C++
int * t = new int( 100 );
intVec.push_back( * t );

//co to za szalone rozwiązanie:P nie możesz po prostu
intVec.push_back( 100 ) //:P Po prostu trzymanie w wektorze wskaźników do inta jest trochę dziwne
P-160293
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.
P-160298
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.
P-160300
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
C/C++
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).
P-160302
« 1 »
  Strona 1 z 1