创建临时文件时std :: function错误的内存访问 [英] std::function bad memory access when creating a temporary

查看:33
本文介绍了创建临时文件时std :: function错误的内存访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在实现一些抽象来表示3D对象的水平集操作.基本上, GLSL着色器的页面对此进行了描述.

I'm currently implementing few abstractions to represent level-set operations for 3D objects. Basically what is described in this amazing page for GLSL shaders.

为了简要概述,可以通过将R ^ 3域映射到标量的一种函数来描述3D对象,该标量称为水平集(或有符号距离函数).例如,对于一个球体,水平集函数由 phi(X)= X.Norm2()-R * R 定义,其中 Norm2 表示平方的欧几里得范数R ^ 3中的向量

To give a brief overview, a 3D object can be described by a function that maps the R^3 domain to a scalar called level-set (or signed-distance-function). For example, for a sphere, the level-set function is defined by phi(X) = X.Norm2() - R*R where Norm2 represents the squared Euclidean norm of a vector in R^3.

所以我提出了一个代表这样一个概念的 LevelSetObject 类:

So I came out with a LevelSetObject class that represents such a concept:

 class LevelSetObject
    {

    using SDFFunction = std::function<double(double, double, double)>;

    protected:
        SDFFunction m_SDF;

    public:

        double SDF(double x, double y, double z) const {
            return m_SDF(x, y, z);
        }

现在,我想在 LevelSetObject 之间定义几个运算符.例如 union 运算符:

Now I wanted to define few operators between LevelSetObjects. For example the union operator:

LevelSetObject LevelSetObject::operator+(const LevelSetObject& other) const {
        LevelSetObject outObj;
        outObj.m_SDF = [this, other]
            (double x, double y, double z) {
                return std::min(m_SDF(x, y, z), other.m_SDF(x, y, z));
            };
        return outObj;
    }

但是当我创建一个临时文件时,由于例如三重和,我遇到了错误的内存访问(而如果像在注释的情况下那样对两个对象分别求和,则使用Valgrind而不是SIGSEV不会发现内存泄漏). LevelSetSphere LevelSetObject 的派生类,在此我专门定义球体的SDF(鉴于其 center 和其 radius )

But I'm experiencing bad memory access when I create a temporary due to, for example, a triple sum (while if I sum the two objects separately as in the commented case, no memory leak is spotted using Valgrind and not SIGSEV). LevelSetSphere is a derived class of LevelSetObject where I define specifically the SDF of a sphere (given its center and its radius)

int main(int argc, char* argv[]) {

    // Generate the central sphere
    double radius = 1.0;
    SimpleVector center(2, 2, 2);
    LevelSetSphere sphere(radius, center);

    // Generate the ears spheres
    LevelSetSphere ear1(radius/2, SimpleVector(1, 1, 2));
    LevelSetSphere ear2(radius/2, SimpleVector(3, 1, 2));

    // Combine objects
    auto mickeyMouse = sphere + ear1 + ear2;
    //auto first = sphere + ear1;
    //auto mickeyMouse = first + ear2;

    // Materialize in the domain

    mickeyMouse.SDF(0.0, 0.0, 0.0);



}

我想是在 operator + 定义中, std :: function 保留了对 other 的引用,当该引用变为悬挂引用时我实际上叫 m_SDF 是因为在三次和期间创建了一个临时目录.我还尝试将 operator + 的签名更改为 operator +(const LevelSetObject other),因此通过副本传递,但结果是相同的.

What I suppose is that in the operator+ definition, the std::function keeps a reference to other that becomes a dangling reference when I actually call m_SDF because a temporary is created during the triple sum. I also tried to change the signature of operator+ to operator+(const LevelSetObject other), so passing by copy, but the outcome is the same.

我在哪里失败?:)

推荐答案

您不好的内存访问不是由于 other 变量引起的,它是指针的 this 指针临时对象超出范围.

Your bad memory access isn't due to the other variable, it's the this pointer of the temp object going out of scope.

您可以通过显式捕获SDF变量来解决此问题,如下所示:

You can fix it by capturing the SDF variables explicitly, like this:

LevelSetObject LevelSetObject::operator+(const LevelSetObject& other) const {
        LevelSetObject outObj;
        auto& SDF=this->m_SDF;
        auto& other_SDF=other.m_SDF
        outObj.m_SDF = [SDF, other_SDF]
            (double x, double y, double z) {
                return std::min(SDF(x, y, z), other_SDF(x, y, z));
            };
        return outObj;
    }

这篇关于创建临时文件时std :: function错误的内存访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆