c++ - 内存泄漏 C++ 线程
问题描述
我有一个问题,可能是 C++ 线程中的内存泄漏。我收到代码 11 的运行时错误。我正在编写一个优化算法,旨在优化 2D 反应器的参数。它生成重整函数的实例,该函数创建重整器对象。重整器有 2 个不同的参数,它们在单个重整器中可以局部不同,并从主函数传递给重整函数。为了指定,每个重整器被划分为指定数量的区域(每个重整器中的尺寸和位置相同),并且每个区域可以具有不同的参数。因此,2 个向量中的每一个的大小等于 [NUMBER OF REFORMERS] * [NUMBER OF ZONES]。然后,重整函数创建 Segment 对象,其数量等于区域的数量。
我认为这里的问题是线程试图同时访问同一个向量,我真的很感激这个问题的解决方案。
评论:
- 如果我更改 main.cpp 以用通常的循环替换线程,则不会返回错误。
- 如果我在 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;
改革者.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)
}
段.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 (-)
};
主.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(); }
}
改革.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);
k++;
}
}
}
解决方案
将 std::ref() 添加到重构函数调用参数解决了这个问题。
for (k = 0; k < spec_max; k++) {
Ref.emplace_back(reforming, k, std::ref(cat), std::ref(porosity));
}
推荐阅读
- javascript - 如何使用包含键在 LoopBack v4 中建立关系
- java - Java中添加两个数字的代码正在向后打印总和?
- sql - 在Oracle的文本中找到单词时如何获取单词的位置?
- c++ - 为什么我的 RLE 代码显示标准超出 c++ 范围?
- php - 防止用户浏览其他页面
- tabulator - Tabulator calculating a total price
- python - 为什么在我的 jupyter notebook 中导入 geopandas 时出现错误?
- jenkins - 我如何设置一个 jenkins 作业,该作业并行调用另一个 jenkins 作业,但使用数组作为参数
- android - 如何在不破坏功能的情况下更改已弃用的房间交易
- java - 一个没有倒数到零的 CountDownLatch 怎么能不被打断返回呢?