Boost :: ошибка доступа к памяти сигнала - PullRequest
4 голосов
/ 26 сентября 2008

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

#include <boost/signal.hpp>

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

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

    Event e;

    return 0;
}

Спасибо! * * 1004

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

Ответы [ 4 ]

6 голосов
/ 29 сентября 2008

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

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

Общая проблема заключается в том, что компоновщик не диагностирует все нарушения одного правила определения (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 сделала свое дело. Обратите внимание, что пробел важен для усиления варенья.

using msvc : 9.0 : : <cxxflags>-D _SECURE_SCL=0 <cxxflags>-D _HAS_ITERATOR_DEBUGGING=0 ;
2 голосов
/ 26 сентября 2008

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

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

1 голос
/ 27 сентября 2010

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

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

x86
ссылка на выпуск bjam отладочная = статическая threading = multi runtime-link = shared Определим = _SECURE_SCL = 0 Определим = _HAS_ITERATOR_DEBUGGING = 0 - со ступенью сигналов

64
ссылка на выпуск bjam отладочная = статическая threading = multi runtime-link = shared Определим = _SECURE_SCL = 0 Определим = _HAS_ITERATOR_DEBUGGING = 0 адрес-модель = 64 - со ступенью сигналов

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

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

1 голос
/ 26 сентября 2008

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

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

...