模板化和 OpenMP 导致 free():在 tcache 2 中检测到双重释放
我已经工作了一段时间,让我的代码成为一个最小的可重现示例,我想我已经有了。请参阅下面的单个 main.cpp
函数,编译方式(在 Linux 上)有两种:
- 串行方式:
g++ -O3 --std=c++17 -o test_rho.exe main。 cpp
- 使用 OpenMP:
g++ -O3 --std=c++17 -fopenmp -o test_rho.exe main.cpp
没有 OpenMP 代码运行良好。 使用 OpenMP,我收到以下错误:
About to return 0
free(): double free detected in tcache 2
使用 OpenMP 时,对 main.cpp
进行以下更改将使此错误消失:
- 不要定义
Wfn( )
构造函数。更具体地说,不要调用_chi.resize(120)
。 - 不要在 OpenMP 循环中使用
private _chi
。 - 不要使用模板(而是在所有内容上使用
double
)。
是什么导致了这里的双重释放?为什么上面的每个更改都能解决问题?
main.cpp:
#include <iostream>
#include <vector>
// Wfn class
template<typename real>
class Wfn {
public:
Wfn() { _chi.resize(120); }
std::vector<real> rho(int nrhos);
private:
std::vector<real> _chi;
};
// Single Wfn function.
template<typename real>
std::vector<real> Wfn<real>::rho(int nrhos) {
std::vector<real> rhos;
rhos.resize(nrhos);
#pragma omp parallel for private (_chi)
for (size_t irho = 0; irho < nrhos; irho++) {
rhos[irho] = (real)irho;
}
return rhos;
}
// Main
int main(int argc, char** argv) {
Wfn<double> wfn;
std::vector<double> rhovs;
rhovs = wfn.rho(1000);
std::cerr << "About to return 0" << std::endl;
return 0;
}
更新:
如果这有帮助,发生这种情况的一般原因是因为 wfn
超出了范围,但我原来的问题仍然存在( s)。如果main改为:
int main(int argc, char** argv) {
{
Wfn<double> wfn;
std::vector<double> rhovs;
rhovs = wfn.rho(1000);
std::cerr << "About to exit scope" << std::endl;
}
std::cerr << "About to return 0" << std::endl;
return 0;
}
那么错误是
About to exit scope
free(): double free detected in tcache 2
I've worked for a while to get my code to a minimal reproducible example and I think I have it. See the single main.cpp
function below, compiled (on Linux) one of two ways:
- In serial:
g++ -O3 --std=c++17 -o test_rho.exe main.cpp
- With OpenMP:
g++ -O3 --std=c++17 -fopenmp -o test_rho.exe main.cpp
Without OpenMP the code runs fine. With OpenMP, I get the following error:
About to return 0
free(): double free detected in tcache 2
When using OpenMP, the following changes to main.cpp
will make this error go away:
- Don't define
Wfn()
constructor. More specifically, don't invoke_chi.resize(120)
. - Don't use
private _chi
in the OpenMP loop. - Don't use templating (instead just use
double
on everything).
What is causing a double free here and why do each of the changes above fix the problem?
main.cpp:
#include <iostream>
#include <vector>
// Wfn class
template<typename real>
class Wfn {
public:
Wfn() { _chi.resize(120); }
std::vector<real> rho(int nrhos);
private:
std::vector<real> _chi;
};
// Single Wfn function.
template<typename real>
std::vector<real> Wfn<real>::rho(int nrhos) {
std::vector<real> rhos;
rhos.resize(nrhos);
#pragma omp parallel for private (_chi)
for (size_t irho = 0; irho < nrhos; irho++) {
rhos[irho] = (real)irho;
}
return rhos;
}
// Main
int main(int argc, char** argv) {
Wfn<double> wfn;
std::vector<double> rhovs;
rhovs = wfn.rho(1000);
std::cerr << "About to return 0" << std::endl;
return 0;
}
Update:
In case this helps, the general reason this is happening is because wfn
is going out of scope, but my original question(s) still remain(s). If main is changed to:
int main(int argc, char** argv) {
{
Wfn<double> wfn;
std::vector<double> rhovs;
rhovs = wfn.rho(1000);
std::cerr << "About to exit scope" << std::endl;
}
std::cerr << "About to return 0" << std::endl;
return 0;
}
Then the error is
About to exit scope
free(): double free detected in tcache 2
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论