This works fine:
std::vector<int> v;
v.push_back(123);
but this throws a std::length_error:
std::vector<uint32_t> v;// or vector<unsigned __int32>
v.push_back(123);
It seems to be triggered by resizing, because
std::vector<uint32_t> v;
v.reserve(2);
triggers a debug assertion "iterator not dereferencable".
This occurs on Visual Studio 2008, but the same code works fine on Mac and Linux. Can anyone suggest a way to narrow down the search for an explanation?
UPDATE:
The rat's nest of static and dynamically linked dependencies in this project made it too time-consuming to find the offending library. I gave up and rebuilt every dependency from source. I lost two days of my life and still don't know exactly where the problem was, but the app runs! Thanks for your help.
This
#include <iostream>
#include <vector>
int main()
{
std::vector<unsigned __int32> v;
v.reserve(2);
std::cout << v.capacity() << '\n';
return 0;
}
runs without any hiccups for me in VS 2008. It prints 2.
What does this do for you? If it works, too, then my first few guesses are:
You invoked undefined behavior somewhere before. By the time execution gets to the code you showed, all bets are off.
This is across DLL boundaries and you linked together DLLs/EXE built with different settings.
The way to find out about this is to distill it down to the smallest possible test case exhibiting the behavior. (That shouldn't contain more than 50LoC, ideally, it's 10.) If you don't find the problem while doing so, append the example to your question.
Since the sample code is working, your sample must be wrong :-)
Try to get closer to the problem by making your sample more like the real code in small steps. At some point it should stop working and then you can identify the culprit.
Can you check if your implementation has two or more typedefs of uint32_t? Especially under different namespaces? (I know the chances are pretty slim, but it might be worth it - in the quest for platform compatibility, different libraries try to map a specific memory size to a type, and one of them might have slipped up).
VC++ 2008 does not provide an ISO C99 header, so you must have provided the definion somehow; perhaps the definition is flawed.
Related
Consider this mock-up of my situation.
in an external header:
class ThirdPartyObject
{
...
}
my code: (spread among a few headers and source files)
class ThirdPartyObjectWrapper
{
private:
ThirdPartyObject myObject;
}
class Owner
{
public:
Owner() {}
void initialize();
private:
ThirdPartyObjectWrapper myWrappedObject;
};
void Owner::initialize()
{
//not weird:
//ThirdPartyObjectWrapper testWrappedObject;
//weird:
//ThirdPartyObject testObject;
}
ThirdPartyObject is, naturally, an object defined by a third party (static precompiled) library I'm using. ThirdPartyObjectWrapper is a convenience class that eliminates a lot of boiler-plating for working with ThirdPartyObject. Owner::initialize() is called shortly after an instance of Owner is created.
Notice the two lines I have labeled as "weird" and "not weird" in Owner::initialize(). All I'm doing here is creating a couple of objects on the stack with their default constructors. I don't do anything with those objects and they get destroyed when they leave scope. There are no build or linker errors involved, I can uncomment either or both lines and the code will build.
However, if I uncomment "weird" then I get a segmentation fault, and (here's why I say it's weird) it's in a completely unrelated location. Not in the constructor of testObject, like you might expect, but in the constructor of Owner::myObjectWrapper::myObject. The weird line never even gets called, but somehow its presence or absence consistently changes the behavior of an unrelated function in a static library.
And consider that if I only uncomment "not weird" then it runs fine, executing the ThirdPartyObject constructor twice with no problems.
I've been working with C++ for a year so it's not really a surprise to me that something like this would be able happen, but I've about reached the limit of my ability to figure out how this gotcha is happening. I need the input of people with significantly more C++ experience than me.
What are some possibilities that could cause this to happen? What might be going on here?
Also, note, I'm not asking for advice on how to get rid of the segfault. Segfaults I understand, I suspect it's a simple race condition. What I don't understand is the behavior gotcha so that's the only thing I'm trying to get answers for.
My best lead is that it has to do with headers and macros. The third party library actually already has a couple of gotchas having to do with its headers and macros, for example the code won't build if you put your #include's in the wrong order. I'm not changing any #include's so strictly this still wouldn't make sense, but perhaps the compiler is optimizing includes based on the presence of a symbol here? (it would be the only mention of ThirdPartyObject in the file)
It also occurs to me that because I am using Qt, it could be that the Meta-Object Compiler (which generates supplementary code between compilations) might be involved in this. Very unlikely, as Qt has no knowledge of the third party library where the segfault is happening and this is not actually relevant to the functionality of the MOC (since at no point ThirdPartyObject is being passed as an argument), but it's worth investigating at least.
Related questions have suggested that it could be a relatively small buffer overflow or race condition that gets tripped up by compiler optimizations. Continuing to investigate but all leads are welcome.
Typical culprits:
Some build products are stale and not binary-compatible.
You have a memory bug that has corrupted the state of your process, and are seeing a manifestation of that in a completely unrelated location.
Fixing #1 is trivial: delete the build folder and build again. If you're not building in a shadow build folder, you've set yourself up for failure, hopefully you now know enough to stop :)
Fixing #2 is not trivial. View manual memory management and possible buffer overflows with suspicion. Use modern C++ programming techniques to leverage the compiler to help you out: store things by value, use containers, use smart pointers, and use iterators and range-for instead of pointers. Don't use C-style arrays. Abhor C-style APIs of the (Type * array, int count) kind - they don't belong in C++.
What fun. I've boiled this down to the bottom.
//#include <otherthirdpartyheader.h>
#include <thirdpartyobject.h>
int main(...)
{
ThirdPartyObject test;
return 0;
}
This code runs. If I uncomment the first include, delete all build artifacts, and build again, then it breaks. There's obviously a header/macro component, and probably some kind of compiler-optimization component. But, get this, according to the library documentation it should give me a segfault every time because I haven't been doing a required initialization step. So the fact that it runs at all indicates unexpected behavior.
I'm chalking this up to library-specific issues rather than broad spectrum C++ issues. I'll be contacting the vendor going forward from here, but thanks everyone for the help.
I'm seeing something weird happening with Visual Studio 2015 Community. Code that worked perfectly in VS2012 crashes at startup when ported to VS2015, before main is invoked: the classic symptoms of some static initialization mess. I have a few static variables, but used properly, with the standard "Construct On First Use" pattern, e.g.:
const int& i()
{
static int *v = new int(1);
return *v;
}
The code above causes an assert from the runtime while initializing the program (see image http://i.stack.imgur.com/nsQGS.png). Pressing retry simply quits the program: no call stack, no information whatsoever.
The code below however works flawlessly:
const int& i()
{
static int *v = nullptr;
if (v == nullptr)
v = new int(1);
return *v;
}
It seems to me that VS2015 is doing what looks like some (illegal) optimization (even in a debug build), by executing the static variable initialization code during program initialization, and not the first time that the function is called, as the C++ standard requires.
I tried several variations of the code above: class methods, free functions, different objects (std::vector, cv::Mat), always with the same result: the static pointer has to be initialized to null or the program doesn't start.
So... am I missing something or is VS2015 actually messing up badly?
UPDATE:
I spent some time trying to find the minimal setup that shows the problem, and this is what I got:
create a project using the "CLR empty project" template.
add a cpp file, containing just the offending function and main(). Main can be empty, it doesn't matter: the bug occurs BEFORE it is even reached.
add 'main' as entry point (or you get a link error).
The x86 version works, but the x64 doesn't.
For comparison, a project with the identical code but created as "Win32 console application" doesn't have the problem, even after adding the /CLR option. I can see differences in the vcxproj files, but none justifies the error, although one or more of them clearly IS the cause.
Is there a way to upload a zip with the project?
Well, #bogdan got it right. My project had a mix of settings that was neither /SUBSYSTEM:CONSOLE nor /SUBSYSTEM:WINDOWS. Once I fixed that, everything started to work as expected. My test projects had the same problem, I blame Microsoft for not having a clear "CLR windows app" C++ template any more in VS2015 (they want to push you to use C# for that, which makes sense most of the times, but not always).
I found this page particularly useful in explaining all the different settings that have to be consistent (it's not just /SUBSYSTEM...).
I wish I could mark #bogdan's comment as answer, but I can't see anything to do that.
Thanks Bogdan!
I have an issue with my code that has some very strange symptoms.
The code is compiled on my computer with the following versions:
a. GCC Version: 4.4.2
b. CMAKE verson: 2.8.7
c. QNX (operating system) version: 6.5.0
And the code has a segfault whilst freeing some memory and exiting from a function (not dying on any code, just on the exit from a function).
The weird things about this are:
The code does it in release mode but not debug mode:
a. The code is threaded so this indicates a race condition.
b. I cannot debug by putting it in debug mode.
The code when compiled on a workmates machine with the same versions of everything, does not have this problem.
a. The wierd things about this are that the workmates code works, but also that the binary created from compiling on his machine, which is the same, is about 6mB bigger.
Now annoyingly I cannot post the code because it is too big and also for work. But can anyone point me along a path to fixing this.
Since I am using QNX I am limited for my debug tools, I cannot use Valgrind and since it is not supported in QNX, GDB doesn't really help.
I am looking for anyone who has had a similar/same problem and what the cause was and how they fixed it.
EDIT:
Sooo... I found out what it was, but im still a bit confused about how it happened.
The culprit code was this:
Eigen::VectorXd msBb = data.modelSearcher->getMinimumBoundingBox();
where the definition for getMinimumBoundingBox is this:
Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();
and it returns a VectorXd which is always initialised as VectorXd output(6, 1). So I immediately thought, right it must be because the VectorXd is not being initialised, but changing it to this:
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();
But this didn't work. In fact I had to fix it by changing the definition of the function to this:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
and the call to this
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);
So now the new question:
What the hell? Why didn't the first change work but the second did, why do I have to pass by reference? Oh and the big question, how the hell didn't this break when my co-worker compiled it and I ran it? Its a straight out memory error, surely it shouldn't depend on which computer compiles it, especially since the compiler and all the other important things are the same!!??
Thanks for your help guys.
... the binary created from compiling on his machine, which is the same, is about 6mB bigger
It's worth figuring out what the difference is (even if it's just the case that his build hides, while yours exposes, a real bug):
double-check you're compiling exactly the same code (no un-committed local changes, no extra headers in the include search path, etc.)
triple-check by adding a -E switch to your gcc arguments in cmake, so it will pre-process your files with the same include path as regular compilation; diff the pre-processor output
compare output from nm or objdump or whatever you have to for your two linked executables: if some system or 3rd-party library is a different version on one box, it may show up here
compare output from ldd if it's dynamically linked, make sure they're both getting the same library versions
compare the library versions it actually gets at runtime too, if possible. Hopefully you can do one of: run pldd, compare the .so entries in /proc/pid/map, run the process under strace/dtrace/truss and compare the runtime linker activity
As for the code ... if this doesn't work:
Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();
// ...
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();
and this does:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
// ...
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);
you presumably have a problem with the assignment operator. If it does a shallow copy and there is dynamically-allocated memory in the vector, you'll end up with two vectors holding the same pointer, and they'll both free/delete it.
Note that if the operator isn't defined at all, the default is to do this shallow copy.
You said you have to change from:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
What was it before?
If it was:
void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd input);
and the copy constructors / assignment operators weren't implemented properly it might have caused the problem.
Please do check how they are both implemented. Here's some info that might help.
General Question which may be of interest to others:
I ran into a, what I believe, C++-compiler optimization (Visual Studio 2005) problem with a switch statement. What I'd want to know is if there is any way to satisfy my curiosity and find out what the compiler is trying to but failing to do. Is there any log I can spend some time (probably too much time) deciphering?
My specific problem for those curious enough to continue reading - I'd like to hear your thoughts on why I get problems in this specific case.
I've got a tiny program with about 500 lines of code containing a switch statement. Some of its cases contain some assignment of pointers.
double *ptx, *pty, *ptz;
double **ppt = new double*[3];
//some code initializing etc ptx, pty and ptz
ppt[0]=ptx;
ppt[1]=pty; //<----- this statement causes problems
ppt[2]=ptz;
The middle statement seems to hang the compiler. The compilation never ends. OK, I didn't wait for longer than it took to walk down the hall, talk to some people, get a cup of coffee and return to my desk, but this is a tiny program which usually compiles in less than a second. Remove a single line (the one indicated in the code above) and the problem goes away, as it also does when removing the optimization (on the whole program or using #pragma on the function).
Why does this middle line cause a problem? The compilers optimizer doesn't like pty.
There is no difference in the vectors ptx, pty, and ptz in the program. Everything I do to pty I do to ptx and ptz. I tried swapping their positions in ppt, but pty was still the line causing a problem.
I'm asking about this because I'm curious about what is happening. The code is rewritten and is working fine.
Edit:
Almost two weeks later, I check out the closest version to the code I described above and I can't edit it back to make it crash. This is really annoying, embarrassing and irritating. I'll give it another try, but if I don't get it breaking anytime soon I guess this part of the question is obsolete and I'll remove it. Really sorry for taking your time.
If you need to make this code compilable without changing it too much consider using memcpy where you assign a value to ppt[1]. This should at least compile fine.
However, you problem seems more like another part of the source code causes this behaviour.
What you can also try is to put this stuff:
ppt[0]=ptx;
ppt[1]=pty; //<----- this statement causes problems
ppt[2]=ptz;
in another function.
This should also help compiler a bit to avoid the path it is taking to compile your code.
Did you try renaming pty to something else (i.e. pt_y)? I encountered a couple of times (i.e. with a variable "rect2") the problem that some names seem to be "reserved".
It sounds like a compiler bug. Have you tried re-ordering the lines? e.g.,
ppt[1]=pty;
ppt[0]=ptx;
ppt[2]=ptz;
Also what happens if you juggle about the values that are assigned (which will introduce bugs in your code, but may indicator whether its the pointer or the array that's the issue), e.g.:
ppt[0] = pty;
ppt[1] = ptz;
ppt[2] = ptx;
(or similar).
It's probably due to your declaration of ptx, pty and ptz with them being optimised out to use the same address. Then this action is causing your compiler problems later in your code.
Try
static double *ptx;
static double *pty;
static double *ptz;
I'm trying to use a std::vector<>::const_iterator and I get an 'access violation' crash. It looks like the std::vector code is crashing when it uses its own internal First_ and Last_ pointers. Presumably this is a known bug. I'm hoping someone can point me to the correct workaround. It's probably relevant that the crashing function is called from an external library?
const Thing const* AClass::findThing (const std::string& label) const
{
//ThingList_.begin() blows up at run time. Compiles fine.
for (std::vector<Thing*>::const_iterator it = ThingList_.begin(); it != ThingList_.end(); ++it) {
//Irrelevant.
}
return 0;
}
Simply calling ThingList_.size() also crashes.
This is sp6, if it matters.
If you're passing C++ objects across external library boundaries, you must ensure that all libraries are using the same runtime library (in particular, the same heap allocator). In practice, this means that all libraries must be linked to the DLL version of MSVCRT.
It's almost certainly a bug in your code and not std::vector. This code is used by way too many projects to have such an easy to repro bug.
What's likely happening is that the ThnigList_ variable has been corrupted in some way. Was the underlying array accessed directly and/or modified?
I agree with Jared that it is probably in your code,
never the less, you should be sure your stl libs are up to date.
The dinkumware site has the patched files you need.
You should update just to be safe