C ++ Векторы / Классы / Threading - PullRequest
1 голос
/ 01 января 2011

Я использую Win7 / VS2008 (9) SDK 6 / 7.1

Я столкнулся с проблемой в коде, который я использую
мини-версия кода следующим образом

class CONNECTION
{
    int/std::string/bool vars; // just to make it simple
    CONNECTION ( int defaultvar );
    CONNECTION ( const CONNECTION& copycon )
    ~CONNECTION ( );
    DWORD static WINAPI staticstart( void *param )  //HACK to use createthread on classes
    { return ((CONNECTION *)param)->main); } // yea it works fine
    DWORD main();
};

этот класс не имеет конструктора по умолчанию с копией, и деструктор все vars копируется нормально, а деструктор не оставляет никаких утечек, конструктор прост, как назначение параметров для var. Все vars и код опущены, чтобы сделать его простыми потому что они не являются проблемой.

class main
{
    std::vector<CONNECTION> con;
    int addcon( int defaultvarofcon )
    {
        CONNECTION temp( defaultvar );
        con.push_back( temp );
        return con.size() - 1;
    }
}

пока все хорошо, когда я запускаю консольную тестовую программу, которая имеет только include, и этот код

main mymainclass;
mymainclass.addcon( 0 );

программа работает нормально, закрывается без ошибок
, но когда я добавляюдополнительный код, такой как

main mymainclass;
mymainclass.addcon( 0 );
mymainclass.addcon( 1 );
mymainclass.addcon( 2 );

, программа падает с нарушением доступа после двойной проверки моего кода. Я отлаживал его шаг за шагом во всех потоках. Я обнаружил, что основной поток может считывать правильные значения всех векторных классов / элементов в обоих основныхпоток и рабочий поток ТОЛЬКО если я использую один элемент в векторе

, однако, если я использую более одного, как второй код, все данные по всем элементам в их собственных потоках недоступны (плохие указатели).но в главном потоке они все еще корректны и показывают правильные значения

Может кто-нибудь, пожалуйста, помогите мне выяснить, что не так с этим кодом?

Ответы [ 2 ]

2 голосов
/ 02 января 2011

std::vector не предназначен для обеспечения резьбы. Поэтому вы должны использовать какой-то мьютекс, чтобы убедиться, что только один поток обращается к нему одновременно.

В противном случае, если какой-либо поток изменяет размер вектора, вектор, возможно, должен будет выделить новое хранилище, скопировать элементы, а затем освободить старое хранилище ... и явно освободить старое хранилище, пока какой-то другой поток использует его, это очень плохо .

Вам необходимо самостоятельно распределить CONNECTION объекты. Разрешение std::vector управлять ими означает, что они будут перемещаться в памяти при изменении размера вектора, а указатели, удерживаемые другими потоками, остаются висящими. Изменение размера вектора делает недействительными все указатели на любое его содержимое.

1 голос
/ 01 января 2011

Если вам нужен пользовательский деструктор и конструктор копирования, вам , вероятно, также потребуется пользовательский оператор присваивания.

Без этого вы быстро получите несколько экземпляров вашего класса, ссылающихся на один и тот жевнутренние указатели / ..., легко приводящие к повреждению памяти и нарушениям доступа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...