内存泄漏C ++线程

我可能有一个问题,原因是C ++线程中的内存泄漏。我收到代码11的运行时错误。我正在编写一个优化算法,旨在优化2D反应堆的参数。它生成重整功能的实例,该实例创建重整对象。重整器具有2个不同的参数,这些参数在单个重整器中可能局部不同,并从主函数传递给重整函数。为了指定,每个重整器被划分为指定数量的区域(每个重整器中相同的尺寸和位置),并且每个区域可以具有不同的参数。因此,两个向量中每个向量的大小等于[REFORMERS的数量] * [ZONE的数量]。然后,重整函数创建Segment对象,该对象的数量等于区域的数量。

我认为这里的问题是线程尝试同时访问相同的向量,对此我真的很感激。

备注:

  1. 如果我更改main.cpp以使用常规循环替换线程,则不会返回任何错误。
  2. 如果我在set_segments函数中注释掉setProp方法,则不会返回任何错误(带有线程)。

由于单个Reformer的计算时间较长,因此强烈建议使用线程,而且我可以使用多核计算单元。

为了澄清,我将用一个最小的可重现示例来解释所有内容:

输入h

#include <iostream>
#include <fstream>
#include <vector>
#include <thread>
int reactor_no = 2;    // number of reformers
int zones_X = 5;       // number of zones in a single reformer, X direction
int zones_Y = 2;       // number of zones in a single reformer, Y direction
double dim_X = 0.5;    // reactor's length    
double dim_Y = 0.2;    // reactor's height
double wall_t = 0.1;   // thickness of the reactor wall
size_t zones = zones_X * zones_Y;

Reformer.h:

#include "input.h"
class Reformer {
public:
    Reformer() {}
    Reformer(const double& L, const double& Y, const double& wall_t, 
                        const int& zones_X = 1, const int& zones_Y = 1) {
        length_ = L;
        height_ = Y;
        zonesX_ = zones_X;
        zonesY_ = zones_Y;
        wall_thickness_ = wall_t;   

        dx_ = length_ / static_cast<double> (zonesX_);
        dr_ = height_ / static_cast<double> (zonesY_);
    }

private:
    double wall_thickness_;         // wall thickness (m)
    double length_;                 // recactor length (m)
    double height_;                 // reactor height (m) (excluding wall thickness)
    int zonesX_;                    // number of segments in the X direction
    int zonesY_;                    // number of segments in the Y direction 
    double dx_;                     // segment width    (m)
    double dr_;                     // segment height (m)
}

Segment.h:

#include "input.h"
class Segment{
public:
    Segment() : Segment(0, 0) {}

    Segment(int i, int j) {
        i_ = i;
        j_ = j;
    }

    void setXR(const double& dx, const double& dr, const int& SL, const int& SR) {
        x0_ = i_ * dx;
        x1_ = x0_ + dx;

        r0_ = j_ * dr;
        r1_ = r0_ + dr;

        if (i_ == SL - 1) {
            x1_ = length;
        }

        if (j_ == SR - 1) {
            r1_ = radius;
        }   
    }

    void setWall() {
        x0_ = 0;
        x1_ = length;

        r0_ = radius;
        r1_ = radius + wall_t;
    }

    void setProp(const double& por, const double& por_s, const bool& cat) {
        porosity_ = por;
        catalyst_ = cat;
    }
private:
    size_t i_;          //segment column no.
    size_t j_;          //segment row no.

    double x0_;         //beginning of segment - x coordinate (m)
    double x1_;         //ending of segment - x coordinate (m)
    double r0_;         //beginning of segment - r coordinate (m)
    double r1_;         //ending of segment - r coordinate (m)

    int catalyst_;      //1 - catalytic, 0 - non-catalytic
    double porosity_;   //porosity (-)

};

main.cpp:

#include "input.h"

int zones = zones_X * zones_Y;

size_t pop_size = reactor_no * zones;
std::vector<int> cat;
cat.reserve(pop_size);
std::vector<double> porosity;
porosity.reserve(pop_size);                // the values in the vectors are not important, therefore I will just fill them with 1s
for (int i = 0; i < pop_size; i++) {
    cat[i] = 1;
    porosity[i] = 1.0;
}

std::vector<std::thread> Ref;
Ref.reserve(reactor_no);
for (k = 0; k < spec_max; k++) {
    Ref.emplace_back(reforming, k, cat, porosity_tab);
}

for (auto &X : Ref) { X.join(); }

Reforming.cpp:

    #include "input.h"

void reforming(const int m, const std::vector<int>& cat_check, const std::vector<double>& por) {                                           
    Reformer reactor(length, radius, wall_t, zonesX, zonesY);

    std::vector<Segment> seg;     // vector holding segment objects                                                                  
    seg.reserve(zones);

    set_segments(seg, reactor, zones, m, por, por_s, cat_check);

}

set_segments函数:

#include "input.h"
void set_segments(std::vector<Segment> &seg, Reformer &reac, const int m, 
                     const std::vector<double> &por, const std::vector<int> &check) {
    int i, j, k, n;

    double dx = dim_X / static_cast<double> (zones_X);
    double dy = dim_Y / static_cast<double> (zones_Y);

    std::vector<Segment*> ptr_seg;
    ptr_seg.reserve(zones);

    k = 0;
    for (i = 0; i < zones_X; i++) {
        for (j = 0; j < zones_Y; j++) {
            n = m * zones + (i * zones_Y + j);
            seg.emplace_back(Segment(i, j));
            seg[k].setProp(por[n], check[n]);
            seg[k].setXR(dx, dy, zones_X, zones_Y);
            seg[k].calcProp();
            k++;
        }
    }

}  
评论