Cra sh в деструкторе shared_ptr в шаблонной функции - PullRequest
0 голосов
/ 03 апреля 2020

В моем 32-битном приложении VS2015 у меня есть шаблонная функция, которая обращается к функциям библиотеки (BTK). В зависимости от типа этой функции вызывается специальная перегрузка c функции этой библиотеки.

Это работает нормально, но в последнее время я использую этот же код и библиотеку (те же двоичные файлы и код) в другом (также 32-битном) VS2015-приложении, и это вызывает segfaults / access access в деструкторе shared_ptr. Если быть точным, то происходит сбой при (взаимосвязанном) уменьшении счетчика использования.

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

Теперь наступает интересная часть: когда я заменяю свою шаблонную функцию на не шаблонную версию, она работает нормально ..

Итак, если я заменим это:

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;
}

на это:

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;
}

Это работает нормально ... Очевидно, что создание шаблона оказывает некоторое влияние на общие указатели. У меня три вопроса:

  • Какое влияние на это могут оказать шаблоны? Я могу себе представить, что создание кода может иметь некоторый эффект, но я не уверен.

  • Почему шаблонная версия будет работать с теми же двоичными файлами и c в одном 32 -битное приложение VS2015, но не в другом? (Где мне нужно прибегнуть к не шаблонным функциям)

  • Какие параметры компилятора / компоновщика могут иметь значение? Я проверил параметры компилятора и компоновщика, но не смог найти соответствующую разницу.

Любая помощь будет оценена.

Бен

1 Ответ

1 голос
/ 04 апреля 2020

Какой эффект могут оказать на это шаблоны? Я могу себе представить, что создание кода может иметь некоторый эффект, но я не уверен.

ADL: метод шаблона будет использовать ADL для поиска зависимых методов (в вашем случае btk::MetaDataInfo::New(dims, values)), тогда как не шаблон учитывает только видимые объявления, поэтому возможная разница.

Пример:

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*
}

Демо

...