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

内存泄漏C++;穿线 我有一个问题,可能是内存在C++线程中泄漏。我收到一个运行时错误,代码为11。我正在写一个优化算法,旨在优化2D反应器的参数。它生成重整函数的实例,该函数创建重整器对象。重整器有两个不同的参数,在单个重整器中可能局部不同,并从主功能传递到重整功能。要指定,每个重整器被划分为指定数量的区域(每个重整器中的尺寸和位置相同),每个区域可以有不同的参数。因此,2个向量中每个向量的大小等于[重整器数量]*[区域数量]。然后,重整功能创建线段对象,其数量等于分区的数量,c++,multithreading,memory-leaks,parallel-processing,stdvector,C++,Multithreading,Memory Leaks,Parallel Processing,Stdvector,我假设这里的问题是线程试图同时访问同一个向量,我非常希望能找到解决方案 备注: 如果我更改main.cpp以使用普通循环替换线程,则不会返回错误 如果在set_segments函数中注释掉setProp方法,则不会返回任何错误(使用线程) 这里强烈推荐线程,因为单个改革器的计算时间很长,而且我可以使用多核计算单元 为了澄清,我将用一个最小的可复制示例来解释一切: 输入.h #include <iostream> #include <fstream> #include &l

我假设这里的问题是线程试图同时访问同一个向量,我非常希望能找到解决方案

备注:

  • 如果我更改main.cpp以使用普通循环替换线程,则不会返回错误
  • 如果在set_segments函数中注释掉setProp方法,则不会返回任何错误(使用线程) 这里强烈推荐线程,因为单个改革器的计算时间很长,而且我可以使用多核计算单元

    为了澄清,我将用一个最小的可复制示例来解释一切:

    输入.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;
    
    main.cpp:

    #include "input.h"
    int main() {
    
        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 < reactor_no; k++) {
            Ref.emplace_back(reforming, k, cat, porosity);
        }
    
        for (auto &X : Ref) { X.join(); }
    }
    
    #包括“input.h”
    int main(){
    int zones=分区X*分区Y;
    尺寸\u t pop\u尺寸=反应器\u no*区;
    病媒猫;
    类别储备(pop_尺寸);
    std::矢量孔隙度;
    孔隙度.储量(pop_size);//向量中的值并不重要,因此我将用1填充它们
    对于(int i=0;i
    .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);
    
    }
    
    #包括“input.h”
    无效重整(常量int m、常量std::vector和cat_check、常量std::vector和por){
    重整反应器(长度、半径、壁厚、区域X、区域Y);
    std::vector seg;//包含段对象的向量
    分段保护区(区域);
    设置分段(分段、反应器、分区、m、por、por s、cat_检查);
    }
    
    设置_段功能:

    #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);
                k++;
            }
        }
    
    }  
    
    #包括“input.h”
    空集_段(标准::矢量和seg、重整器和reac、常数int m、,
    常量标准::向量和端口,常量标准::向量和检查){
    int i,j,k,n;
    双dx=尺寸X/静态铸造(分区X);
    双dy=尺寸Y/静态铸造(区域Y);
    std::向量ptr_seg;
    ptr_分段保护区(区域);
    k=0;
    对于(i=0;i<0;i++){
    对于(j=0;j<0;j++){
    n=m*区域+(i*区域_Y+j);
    分段后侵位(段(i,j));
    seg[k].setProp(por[n],check[n]);
    seg[k].setXR(dx,dy,zones\ux,zones\uy);
    k++;
    }
    }
    }  
    
    将std::ref()添加到函数调用参数解决了问题

    for (k = 0; k < spec_max; k++) {
            Ref.emplace_back(reforming, k, std::ref(cat), std::ref(porosity));
    }
    
    (k=0;k{ 基准侵位(重整,k,标准::基准(cat),标准::基准(孔隙度)); }
    内存泄漏不应产生运行时错误。“你的<代码>主< /COD>函数”?DmitryKuzminov,我不是C++向导,所以我不知道“运行时错误”是否有一些特殊的、狭隘的含义,我不知道,但是程序不能永远泄漏内存。有些坏事终究会发生。@Padzak,这里可能有人能提供帮助,只要他们知道“代码11”是什么意思。请您将错误消息的全文添加到问题中,并告诉我们运行该程序的操作系统以及您用来构建该程序的工具是什么?什么是
    spec\u max
    ,为什么只保留
    reactor\u no==2个
    线程?我为不一致性道歉,我很自责,有时还有些挣扎。我正在使用CLion,代码11由IDE返回。两个线程只是一个例子,在原始代码中我生成了30个线程。
    
    #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);
                k++;
            }
        }
    
    }  
    
    for (k = 0; k < spec_max; k++) {
            Ref.emplace_back(reforming, k, std::ref(cat), std::ref(porosity));
    }