简体   繁体   English

模板化 function 中的 shared_ptr 析构函数崩溃

[英]Crash in shared_ptr destructor in templated function

In my 32-bit VS2015 application, I have a templated function that accesses functions of a library (BTK).在我的 32 位 VS2015 应用程序中,我有一个模板化的 function 可以访问库 (BTK) 的功能。 Depending on the type of this function, a specific overload of a function of this library is called.根据此 function 的类型,调用此库的 function 的特定重载。

This works fine, but recently I'm using this same code and library (same binaries and code) in another (also VS2015 32-bit) application, and it segfaults/access violation in the destructor of shared_ptr .这工作正常,但最近我在另一个(也是 VS2015 32 位)应用程序中使用相同的代码和库(相同的二进制文件和代码),并且它在shared_ptr的析构函数中出现段错误/访问冲突。 To be precise, it crashes at the (interlocked) decrement of the use count.准确地说,它在使用计数的(联锁)递减时崩溃。

void _Decref()
{   // decrement use count
    if (_MT_DECR(_Uses) == 0) // BOOM
    {   // destroy managed resource, decrement weak reference count
        _Destroy();
        _Decwref();
    }
}

Now comes the interesting part, when I replace my templated function with a non-templated version, it works fine..现在到了有趣的部分,当我用非模板版本替换我的模板 function 时,它工作正常..

So, if I replace this:所以,如果我替换这个:

template<class T>
bool SetParameters(const std::string& group, const std::string& param, const std::vector<T>& values, const std::vector<uint8_t>& dims)
{
    btk::MetaData::Pointer pParam = GetBtkMetaData(group, param);
    if (!pParam)
    {
        pParam = AddBtkMetaData(group, param);
    }

    if (!pParam->HasInfo())
    {
        pParam->SetInfo(btk::MetaDataInfo::New(dims, values));
    }
    else pParam->GetInfo()->SetValues(dims, values);

    return true;
}

with this:有了这个:

bool C3DFile::SetParameters(const std::string& group, const std::string& param, const std::vector<int16_t>& values, const std::vector<uint8_t>& dims)
{
    btk::MetaData::Pointer pParam = GetBtkMetaData(group, param);
    if (!pParam)
    {
        pParam = AddBtkMetaData(group, param);
    }

    if (!pParam->HasInfo())
    {
        pParam->SetInfo(btk::MetaDataInfo::New(dims, values));
    }
    else pParam->GetInfo()->SetValues(dims, values);

    return true;
}

It works fine... Apparantly, the template-instantiation has some effect on the shared pointers.它工作正常......显然,模板实例化对共享指针有一些影响。 I have three questions:我有三个问题:

  • What kind of effect could templates have on this?模板可以对此产生什么样的影响? I can imagine that the code instantiation could have some effect, but I'm not sure.我可以想象代码实例化可能会产生一些影响,但我不确定。

  • Why would the templated version work, with the same binaries etc, in one 32-bit VS2015 app, but not in the other?为什么模板化版本可以在一个 32 位 VS2015 应用程序中使用相同的二进制文件等工作,而在另一个应用程序中却不行? (Where I need to resort to non-templated functions) (我需要使用非模板函数的地方)

  • Which compiler/linker options could be relevant?哪些编译器/链接器选项可能相关? I checked the compiler and linker options, but couldn't find a relevant difference.我检查了编译器和 linker 选项,但找不到相关的区别。

Any help would be appreciated.任何帮助,将不胜感激。

Ben

What kind of effect could templates have on this?模板可以对此产生什么样的影响? I can imagine that the code instantiation could have some effect, but I'm not sure.我可以想象代码实例化可能会产生一些影响,但我不确定。

ADL: the template method will use ADL to find the dependent methods (in your case btk::MetaDataInfo::New(dims, values) ), whereas the non template only considers visible declarations, so the possible difference. ADL:模板方法将使用 ADL 查找依赖方法(在您的情况下为btk::MetaDataInfo::New(dims, values) ),而非模板仅考虑可见声明,因此可能存在差异。

Example:例子:

struct A{};

void fooT(const void*) { std::cout << "void*\n"; }
template <typename T> void barT(const T* p) { fooT(p); }
void fooT(const A*) { std::cout << "A*\n"; }

void foo(const void*) { std::cout << "void*\n"; }
void bar(const A* p) { foo(p); }
void foo(const A*) { std::cout << "A*\n"; }

int main()
{
    A a{};

    barT(&a); // fooT(const A*)   -> A*
    bar(&a);  // foo(const void*) -> void*
}

Demo演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM