dynamic cast throws pointer is not std::__non_rtti_object - c++

I'm having problem with dynamic_cast. i just compiled my project and tested every thing in debug mode and then i tried compiling it in release mode, i have copied every configuration from debug mode exept optimization parameter which is now /o2, (while debuging i set it as /od) the project compiled but when it starts loading my resources i got exception in the piece of code here :
for(int j = 1; j < i->second->getParametersNumber();j++)
{
CCTMXTiledMap* temp = CCTMXTiledMap::tiledMapWithTMXFile(i->second->As<string>(j).c_str());
CCTMXLayer* ret = NULL;
for(NSMutableArray<CCNode*>::NSMutableArrayIterator l=temp->getChildren()->begin();!ret && l!=temp->getChildren()->end();l++)
ret = dynamic_cast<CCTMXLayer*> (*l);
t1.first = ret;
templates[i->first].second.push_back(t1);
templates[i->first].second.back().first->retain();
}
nothing in code changed and when I check in debugger every variable in classes is what it should be but dynamic cast is throwing std::__non_rtti_object. what am i doing it wrong? and i'm using cocos2d-x ,I didn't have enough reputation to add that tag!

Does CCNode have any virtual functions? Are all elements of temp->getChildren()->begin() really CCNodes? Does temp->getChildren() return a reference? The latter is especially insidious: you call both temp->getChildren()->begin() and temp->getChildren()->end(). If getChildren() returns a copy, you're taking the begin of one copy and the end of another copy.

In this case after many code changes I found out there has to be some bugs which show themselves when code is optimized (still don't know if it's compiler's mis optimization or my code has some problems but it's probably mine). and the main reason for that problem was with *l being NULL.

Related

VS2015 C++ static initialization crash, possible bug

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!

C++ variable address does not match

class CCtrl
{
...Other Members...
RankCache m_stRankCache;
uint32 m_uSyncListTime;
};
int CCtrl::UpdateList()
{
uint32 tNow = GetNowTime();
for (uint8 i = 0; i < uRankListNum; i++)
{
m_stRankCache.Append(i);
}
m_uSyncListTime = tNow;
return 0;
}
Here are two weired things:
When step into Append(), p this = 0x7f3f467edfdc, but in UpdateGuildList(), p &m_stRankCache = 0x7f3f067edfdc, these two pointers are different.
tNow = 1418916316, after executing m_uSyncListTime = tNow, m_uSyncListTime is still 0.
How could this happen? I've used a whole day for debugging. And I checked my code there is no pack(1) and pack() mismatch.
The issue is more than likely that you're using your debugger to debug code that has been optimized. As your comment suggested, you are debugging code that has been compiled with the -O3 flag, denoting optimization.
Even though you're using gdb, the Visual Studio and other debuggers also have the same issue, and that issue is debugging optimized code and having the debugger "work" in the sense that the debugger follows along with the lines in the source code, along with the variables that have been declared.
A debugger assumes that the lines of the source code match up with the generated assembly code. With optimizations turned on, this can no longer be the case. Code and variables are eliminated, moved, etc. Therefore the lines in the code (including variable declarations) you believe should be there at a certain location may not be there in the final optimized build.
The debugger cannot discern these changes, thus you get erroneous values used for variables, or in some cases, you get "variable doesn't exist" errors reported by your debugger.
Also, it may also serve as a good check to do a simple cout or log of the values in question if there is a problem with the debugging environment. There are situations where even debuggers may get things wrong, so a backup verification system (i.e. logging, printf() or cout statements, etc.) should be used.

Error in release build only, copying structure from std::vector

I'm having a weird problem trying to get my release build working in Xcode 4.2 using llvm. I've turned off all optimisation settings for the release scheme, and as far as I can tell the release build matches all the settings of the debug build. Regardless of this, the following problem occurs when working with some structures from Box2D, a physics library - but I am unsure if the problem has anything todo specifically with that.
b2CircleShape* circleShape = new b2CircleShape();
circleShape->m_p.Set(0,0);
circleShape->m_radius = m_radius;
b2FixtureDef fixture;
fixture.shape = circleShape;
fixture.density = m_density;
m_fixtureDefs.push_back(fixture); // std::vector
b2FixtureDef fix2 = fixture;
b2FixtureDef fix3 = m_fixtureDefs[0] // EXC_BAD_ACCESS
When I remove all instances of access to m_fixtures, no problems occur. When I run in the development scheme no errors occur. I am really, really confused, if someone could point me in the right direction for errors to look for it would be much appreciated
EDIT:
More interesting stuff
for (vector<b2FixtureDef>::iterator i = m_fixtureDefs.begin() ; i != m_fixtureDefs.end(); ++i)
{
}
This appears to loop forever, making me very confused. It seems like the structure m_fixturesDef has some kind of problem, but I have no idea why whatever weird corruption is going on is only occurring in this particular variable.
By default POD objects are not initializes in C++ so their initial value (unless explicitly initialized) are inherently random.
When you build in debug mode the compiler usually inserts extra initialization code to zero out values. Thus you can easily see different behaviors between debug and release builds.
A quick way to find this kind of problem is to check your compiler warnings; see if you are using a variable before it has been initialization (you may need to turn on the warnings) or something similar.
Note: You can fix a lot of serious problems by making sure your code compiles with zero warnings with the warning level as high as reasonable (usually a step above default). (a warning is really a logical error in your code).

A question about the code exception

Env: VS 2008, C++
I have code like below:
void HopeException(LPVOID nVerify)
{
char *p = NULL;
p = (char *)nVerify;
delete []p;
}
When I invoke the function "HopeException" with parameter not-NULL, like:
HopeException(123);
then I hope the program will throw an exception.
But when I compile the code on VS 2008 with Release mode, the program runs well.
I don't know why. Could anyone give me a help about this issue?
Or do you have any good idea to implement the feature with another method?
Edit:
I am so sorry, I think I posted the wrong code before.
Actually, I am doing protection for my software.
My software will get the CRC value of DLL file, and then my software will check the CRC value like below:
unsigned int VerifyCRC = FF234322;
unsinged int CRC = getCRC("Fun.dll");
LPVOID lpResult = CRC & (~VerifyCRC);
HopeException(lpResult);
So according the code below, if the cracker cracks the Fun.dll file, the execute will throw out an exception.
That is really I want.
Jell - C++ gives you enough rope to hang yourself (and most probably most of you friends).
But why do it? (- Suppose it depends on your friends).
You're treating nVerify as an address and assigning it to your pointer p, and then invoking delete[] on that address. If the value of nVerify isn't a valid address you can get undefined behavior, which includes the program appearing to "run well" mostly because you're not really doing much in this function.
What are you really trying to do?
That code shouldn't compile in C++; the closest thing that should compile fine is:
void HopeException(int nVerify)
{
char *p = NULL;
p = (char *)nVerify;
delete []p;
}
This code will crash on VS 2010 Express, so I assume it will also crash in VS 2008. If your goal is to throw a debugger exception directly (on x86) you can just use
__asm int 3;
If your goal is to break into the debugger you can also just use
DebugBreak();

w8004 compiler warning BDS6 c/c++

It is a best practise to initialise a variable at the time of declaration.
int TMyClass::GetValue()
{
int vStatus = OK;
// A function returns a value
vStatus = DoSomeThingAndReturnErrorCode();
if(!vStatus)
//Do something
else
return(vStatus);
}
In the debug mode, a statement like this int vStatus = OK; is causing no issues during DEBUG MODE build.
The same when build in RELEASE MODE, throws a warning saying:
w8004: 'vStatus' is assigned a value that is never used.
Also, i am using the same variable further down my code with in the same function,like this if(!vStatus)and also I return the value of return(vStatus);
When I looked at the web for pointers on this debug Vs Release, compilers expect you to initialise your variable at the time of declaring it.
I am using Borland developer studio 6 with windows 2003 server.
Any pointers will help me to understand this issue.
Thanks
Raj
You initialise vStatus to OK, then you immediately assign a new value.
Instead of doing that you should initalise vStatus with a value that you're going to use.
Try doing the following instead:
int TMyClass::GetValue()
{
// A function returns a value
int vStatus = DoSomeThingAndReturnErrorCode();
if(!vStatus)
//Do something
else
return(vStatus);
}
Edit: Some clarification.
Initialising a variable, only to never use that value, and then to assign another value to the variable is inefficient. In your case, where you're just using int's it's not really a problem. However, if there's a large overhead in creating / copying / assignment for your types then the overhead can be a performance drain, especially if you do it a lot.
Basically, the compiler is trying to help you out and point out areas in your program where improvements can be made to your code
If you're wondering why there's no warning in debug mode, it's because the passes that perform dataflow analysis (which is what finds the problem) are only run as part of optimization.