模板化和 OpenMP 导致 free():在 tcache 2 中检测到双重释放

发布于 2025-01-20 03:34:35 字数 2104 浏览 4 评论 0原文

我已经工作了一段时间,让我的代码成为一个最小的可重现示例,我想我已经有了。请参阅下面的单个 main.cpp 函数,编译方式(在 Linux 上)有两种:

  1. 串行方式:g++ -O3 --std=c++17 -o test_rho.exe main。 cpp
  2. 使用 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:

  1. In serial: g++ -O3 --std=c++17 -o test_rho.exe main.cpp
  2. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文