C++ Threading с многомерными векторами-нарушение доступа

В настоящее время я пытаюсь выполнить работу в потоковой функции-члене моего класса. Поэтому он получает 2d массив в качестве параметра и заполняет его в функции-члене. Это повторяется несколько раз. Сразу после создания первого потока я получаю ошибку с нарушением прав доступа на чтение или запись. Я пробовал разные подходы к его решению, но не могу заставить его работать. Хотя я нашел почти любую проблему, уже решенную здесь, в этом случае мне не удалось найти что-то в течение довольно долгого времени.

void myClass::process(Vector3D& out_stack, long filterFaktor){
    long rowSize = this->input2D.size();
    long colSize = this->input2D.at(0).size();
    int filterPerRowCount = ceil((double)rowSize / filterFaktor);
    int filterPerColCount = ceil((double)colSize / filterFaktor);   

    std::vector<std::thread> threadPool;
    //create new filter
    long currentrow = 0;    
    while (currentrow < rowSize) {
        long currentcol = 0;
        while (currentcol < colSize) {          
            Filter* nextFilter = &this->createNextFilter(currentrow, currentcol, filterPerRowCount, filterPerColCount);                             
            out_stack.push_back(Vector2D());
            Vector2D* nptr = &out_stack[out_stack.size()-1];

            //Here we are calling the thread which leads to the access violation
            threadPool.push_back(std::thread(&myClass::nextProcess, this, nextFilter, nptr, rowSize, colSize));

            currentcol += filterPerColCount;            
        }
        currentrow += filterPerRowCount;
    }   
    //wait until threads have finished
    for (int iThread = 0; iThread < threadPool.size(); iThread++) {
        threadPool[iThread].join();
    }
}

void myClass::nextProcess(Filter* nextfilter, Vector2D* out_Map, long rowCount, long colCount){
    //Loops this part -> creates the rows and pushes them in the out_Map
        std::vector<double> nextRowInMap;
        //... Calculates sum
        nextRowInMap.push_back(sum);        

    //Push row in vector -> This is where the error occurs
    out_Map->push_back(nextRowInMap);       
}       


typedef std::vector<double> Vector1D;
typedef std::vector<Vector1D> Vector2D;
typedef std::vector<Vector2D> Vector3D;

Я думаю, что мне просто не хватает знаний в использовании указателей в C++, потому что я новичок в этом.

Заранее спасибо и с наилучшими пожеланиями

РЕДАКТИРОВАТЬ

Попробовал это сейчас таким образом, до сих пор не работает:

out_stack.push_back(Vector2D());
long index = out_stack.size() - 1;                  
threadPool.push_back(std::thread(&myClass::nextProcess, this, nextFilter, &out_stack, index, rowSize, colSize));

И в nextProcess:

out_stack->at(index).push_back(nextRowInMap);

РЕДАКТИРОВАТЬ

Решается с mutex. Кроме того, мне нужно было пройти фильтр не по ссылке.

1 ответ

  1. Вы ошибка здесь:

    out_stack.push_back(Vector2D());
    Vector2D* nptr = &out_stack[out_stack.size()-1];
    

    Нет никакой гарантии, что объект останется по тому же адресу при изменении вектора.
    Когда вектор должен расти, он может выделить внутреннюю память на другой адрес и переместить объекты в векторе на новый адрес. Таким образом, указатель может стать недействительным на следующем push_back

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

    out_stack[index].push_back(...)
    

    Это может быть, что после out_stack[index]и до push_backвектор будет изменен, и вы также работаете на недопустимой памяти. Таким образом, вы должны защитить доступ/изменение вектора с помощью a std::mutex. Я не уверен в этой последней части, хотя, если есть какая-то гарантия безопасности нити, я не знаю.