Boost:: ошибка доступа к памяти сигнала

Я пытаюсь использовать boost:: signal для реализации механизма обратного вызова, и я получаю подтверждение доступа к памяти в коде boost:: signal даже при самом простом использовании библиотеки. Я упростил его до этого кода:

#include <boost/signal.hpp>

typedef boost::signal<void (void)> Event;

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

    Event e;

    return 0;
}

Спасибо!

Редактировать: Это был Boost 1.36.0, скомпилированный с Visual Studio 2008 с пакетом обновления 1 (SP1). Boost::filesystem, как boost:: signal, также имеет библиотеку, которая должна быть связана, и, кажется, работает нормально. Я полагаю, что все остальные библиотеки расширения, которые я использую, предназначены только для заголовков.

4 ответа

Решение

Я проверил ваш код в моей системе, и он отлично работает. Я думаю, что есть несоответствие между вашим компилятором и компилятором, на котором построена ваша библиотека Boost.Signals. Попробуйте загрузить исходный код Boost и скомпилируйте Boost.Signals, используя тот же компилятор, который вы используете для сборки своего кода.

Просто для моей информации, какой компилятор (и версия) вы используете?

Я подтвердил это как проблему - об этом написал блог Стефан Т Лававей (STL!) Из Microsoft.

В частности, он сказал:

Общая проблема заключается в том, что компоновщик не диагностирует все нарушения One Definition Rule (ODR). Хотя это и не невозможно, но это трудная проблема для решения, поэтому Стандарт специально разрешает определенные нарушения УСО без диагностики.

Мне бы очень хотелось, чтобы компилятор и компоновщик имели специальный режим, который бы отслеживал все нарушения ODR во время сборки, но я признаю, что это будет трудно достичь (и потребует ресурсы, которые, возможно, могут быть использованы еще лучше, например, больше соответствия). В любом случае нарушения ODR можно избежать без особых усилий, правильно структурировав код, поэтому мы, программисты, можем справиться с отсутствием проверки компоновщика.

Однако макросы, которые изменяют функциональность кода путем включения и выключения, опасно заигрывают с ODR, и особая проблема заключается в том, что _SECURE_SCL и _HAS_ITERATOR_DEBUGGING оба делают именно это. На первый взгляд, это может показаться не таким уж плохим, так как вы уже должны контролировать, какие макросы определены в проекте в вашей системе сборки. Однако отдельно скомпилированные библиотеки усложняют ситуацию - если вы собрали (например, Boost) с включенным _SECURE_SCL (по умолчанию), ваш проект не должен отключать _SECURE_SCL. Если вы намереваетесь отключить _SECURE_SCL в своем проекте, теперь вам нужно соответствующим образом пересобрать Boost. И в зависимости от рассматриваемой отдельно скомпилированной библиотеки, это может быть сложно (с Boost, насколько я понимаю, это можно сделать, я просто никогда не понимал, как).

Он перечисляет некоторые возможные обходные пути позже в комментарии, но ни один не выглядел подходящим для этой ситуации. Кто-то еще сообщил о возможности отключить эти флаги при компиляции boost, вставив некоторые определения в boost / config / compiler / visualc.hpp, но это НЕ сработало для меня. Однако вставка следующей строки VERBATIM в tools/build/v2/user-config.jam сделала свое дело. Обратите внимание, что пробелы важны для повышения варенья.

используя msvc: 9.0::  -D _SECURE_SCL = 0  -D _HAS_ITERATOR_DEBUGGING = 0;

Такая проблема часто возникает при компиляции с другой реализацией кучи. В VS можно попросить, чтобы CRT был связан (как статическая библиотека) или оставлен как динамическая библиотека.

Если используемая вами библиотека выделяет память в своей связанной куче, и ваша программа пытается освободить ее, используя другую кучу, вы попадаете в беду: объекта, который нужно освободить, нет в списке объектов, которые были выделены.

Брайан, я только что столкнулся с той же проблемой, что и ты. Благодаря вашему ответу о посте в блоге я отследил его до нашего отключения _HAS_ITERATOR_DEBUGGING а также _SECURE_SCL,

Чтобы решить эту проблему, я создал библиотеки повышения вручную. Мне не нужно было возиться с файлами конфигурации. Вот две командные строки, которые я использовал:

x86
Ссылка на выпуск отладки bjam = статическая многопоточность = многостанальная связь = общее определение =_SECURE_SCL=0 define=_HAS_ITERATOR_DEBUGGING=0 - со стадией сигналов

x64
ссылка на выпуск bjam для отладки = статическая многопоточность = многостанционная ссылка = общее определение = _SECURE_SCL = 0 define = _HAS_ITERATOR_DEBUGGING = 0 модель адреса =64 - этап с сигналами

Это создает следующие файлы:
libboost_signals-vc90-мт-1_43.lib
libboost_signals-vc90-мт-Г.Д.-1_43.lib

Надеюсь, это поможет.

Другие вопросы по тегам