Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost::signal memory access error

I'm trying to use boost::signal to implement a callback mechanism, and I'm getting a memory access assert in the boost::signal code on even the most trivial usage of the library. I have simplified it down to this code:

#include <boost/signal.hpp>

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

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

    Event e;

    return 0;
}

Thanks!

Edit: This was Boost 1.36.0 compiled with Visual Studio 2008 w/ SP1. Boost::filesystem, like boost::signal also has a library that must be linked in, and it seems to work fine. All the other boost libraries I use are headers-only, I believe.

like image 632
Brian Stewart Avatar asked Dec 31 '22 10:12

Brian Stewart


2 Answers

I have confirmed this as a problem - Stephan T Lavavej (STL!) at Microsoft blogged about this.

Specifically, he said:

The general problem is that the linker does not diagnose all One Definition Rule (ODR) violations. Although not impossible, this is a difficult problem to solve, which is why the Standard specifically permits certain ODR violations to go undiagnosed.

I would certainly love for the compiler and linker to have a special mode that would catch all ODR violations at build time, but I recognize that that would be difficult to achieve (and would consume resources that could perhaps be put to even better use, like more conformance). In any event, ODR violations can be avoided without extreme effort by properly structuring your code, so we as programmers can cope with this lack of linker checking.

However, macros that change the functionality of code by being switched on and off are flirting dangerously with the ODR, and the specific problem is that _SECURE_SCL and _HAS_ITERATOR_DEBUGGING both do exactly this. At first glance, this might not seem so bad, since you should already have control over which macros are defined project-wide in your build system. However, separately compiled libraries complicate things - if you've built (for example) Boost with _SECURE_SCL on, which is the default, your project must not turn _SECURE_SCL off. If you're intent on turning _SECURE_SCL off in your project, now you have to re-build Boost accordingly. And depending on the separately compiled library in question, that might be difficult (with Boost, according to my understanding, it can be done, I've just never figured out how).

He lists some possible workarounds later on in a comment, but none looked appropriate to this situation. Someone else reported being able to turn off these flags when compiling boost by inserting some defines in boost/config/compiler/visualc.hpp, but this did NOT work for me. However inserting the following line VERBATIM in tools/build/v2/user-config.jam did the trick. Note that the whitespace is important to boost jam.

using msvc : 9.0 : : <cxxflags>-D _SECURE_SCL=0 <cxxflags>-D _HAS_ITERATOR_DEBUGGING=0 ;
like image 135
Brian Stewart Avatar answered Jan 13 '23 12:01

Brian Stewart


This kind of problem often occurs when compiling with a different heap implementation. In VS, it is possible to ask for the CRT to be linked in (as a static library), or left as a dynamic library.

If the library you use allocates memory on its linked-in heap, and your program tries to deallocate it, using another heap, you get in trouble: the object to be freed is not on the list of objects that were allocated.

like image 20
xtofl Avatar answered Jan 13 '23 11:01

xtofl