Jump to content
  • Advertisement
Sign in to follow this  
WuTz

Can "this" be NULL?

This topic is 3026 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi! I have another problem: When I want to build my Engine in the Release-mode, I just jumps over a lot of code, without triggering any DebugOutputs, MsgBoxes, or any other functions. I found out, that this is because of the code-optimizations. (In debug mode it works just perfectly)
void WMeshHandler::LoadFromPackage(LPWSTR Package,LPWSTR File)
{ //<---------------- from here
if(!this)
	{
		return; //Todo: WTF!?
	}
	void* Vertices;
	DWORD* Indices;
	DWORD* Attributes;





	if(wcslen(Package)<=0 || wcslen(File)<=0)
	{
		WarnBox(L"Warning! [w]tech trys to load a mesh, without having any Package information passed to the LoadFromPackage() function!");
		return;
	}



	long Size;
	CreateFromDataStruct ds;

	WCHAR n[MAX_PATH];

	WTechPackage2* Pck;
	PckHandler->FindPackageByName(Package,&Pck);
	if(!Pck)
	{
		WCHAR Msg[256];

		wsprintf(LPS Msg,L"Could NOT find a package called \"%s\"! Loading of Mesh \"%s\" failed! WTech may crashes now!",Package,File);
		ErrorBox(LPS Msg);
		return;
	}
	WCHAR fn[MAX_PATH];
	wcscpy(LPS fn,File);
	Pck->GetFileName(File); //Strip the .Ext if there is any

	OutputDebugString(L"WMeshNumVertices\n");
	wcscpy(LPS n,File);
	wcscat(LPS n,L".WMeshNumVertices");
	if(Pck->GetVariableFile(LPS n,&ds.NumVertices,NULL)==false)
	{
		ErrorBox(L"Could NOT load the mesh from the Package!");
		return;
	}

	OutputDebugString(L"WMeshNumFaces\n");
	wcscpy(LPS n,File);
	wcscat(LPS n,L".WMeshNumFaces");
	Pck->GetVariableFile(LPS n,&ds.NumFaces,NULL);

	
		
	
	OutputDebugString(L"WMeshNumIndices\n");
	wcscpy(LPS n,File);
	wcscat(LPS n,L".WMeshNumIndices");
	Pck->GetVariableFile(LPS n,&ds.IndicesNum,NULL);

	OutputDebugString(L"WMeshVertex\n");
	wcscpy(LPS n,File);
	wcscat(LPS n,L".WMeshVertex");
	Pck->GetFile(LPS n,(byte **)&Vertices,(UINT *)&Size);
	ds.Vertices=Vertices;
	
	OutputDebugString(L"WMeshIndex\n");
	wcscpy(LPS n,File);
	wcscat(LPS n,L".WMeshIndex"); //<------------- To here!
	Pck->GetFile(LPS n,(byte **)&Indices,NULL);
	ds.Indices=Indices;

	OutputDebugString(L"WMeshAttribute\n");
	wcscpy(LPS n,File);
	wcscat(LPS n,L".WMeshAttribute");
	Pck->GetFile(LPS n,(byte **)&Attributes,NULL);
	ds.Attributes=Attributes;

	CreateMeshFromData(ds,Package,LPS fn);

	/*delete[] Vertices;
	delete[] Indices;
	delete[] Attributes;*/
}

And one more mysterious thing: The "this"-pointer is NULL... Can that be? Since I know that "code-jumping" is because of the code optimizations, I turned them off. This means: Copied the Debug profile, changed the runtime library and the preDefines to the release ones. Here, it crashes, because "this" is NULL, too! Help would be great! :D

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by WuTz
And one more mysterious thing: The "this"-pointer is NULL... Can that be?
Yes:
WMeshHandler* pFoo = NULL;
pFoo->LoadFromPackage(L"Blah", L"Blah2");

Share this post


Link to post
Share on other sites
The compiler won't "optimize out" any code that has side effects.
You are probably stepping through your program without debugging information.

As for the crash, you are invoking the member function on a NULL pointer, could you post the code where the method was invoked from? Look in the call stack when it crashes.

Edit: Argh, beaten.

Share this post


Link to post
Share on other sites
Quote:
Original post by WuTz
The "this"-pointer is NULL... Can that be?

Sure.

#include <iostream>

struct Foo
{
void print_this()
{
std::cout << this << std::endl;
}
};

int main()
{
Foo* p = 0;
p->print_this();
}

Share this post


Link to post
Share on other sites
remember how the whole this-pointer mechanism actually works internally.
upon calling a non-static class method, the compiler implicitly passes a pointer to the called object as first parameter. this is what's called a thiscall, opposed to the stdcall calling convention of ordinary functions.

now when you do something like this:

MyClass* c = NULL;
c->SomeMethod();



then the this pointer inside SomeMethod will evaluate to NULL. c++ does not check this on calling, so if you're trying to access any member of MyClass, the whole thing will crash. that's probably what happened in your code.

[Edited by - ComicSansMS on March 31, 2010 8:47:03 AM]

Share this post


Link to post
Share on other sites
Hey! Great work! :)

I found out, that DXUT has decided to don't call my InitEngine function, where the pointer to the PackageHandler gets passed to my Scene-Class, which passes them to all Objects. And because this pointer was NULL, any other where NULL! :)

Thx for all the help! :D

Share this post


Link to post
Share on other sites
Beware though, that if the class has any virtual functions in it it will most likely crash when calling one of them.



struct Foo
{
virtual void bar();
};


...

Foo* foo = 0;
foo->bar(); // Crash!





Share this post


Link to post
Share on other sites
Quote:
Original post by phresnel
Quote:
Original post by ComicSansMS


Please, oh please, tell me that you are not a fan of comic sans


more like a fan of irony [rolleyes]

sorry for ot.

Share this post


Link to post
Share on other sites
Haven't ever tried calling members from the "null memory". Now I'm just thinking about it:

struct mystruct
{
// no memory used, just 1 byte used by compiler (I assume sizeof( struct )== 1)

void dododo( void )
{
// <...>
}
};

struct mystruct* p= 0;
p->dododo();

Tell me why p->do(); should crash. mystruct occupies no memory; 1 byte (or more, always depends) probably is occupied by a compiler. It might crash only if there is no preprocessing/optimization/etc. Compiler could simply make it static, because there is no other memory manually occupied in mystruct by user/developer. So, if I were a compiler, I would simply translate it into this peace of code:

struct mystruct
{
static void dododo( void )
{
// <...>
}
};

mystruct::dododo();

Only if there is a polymorphism, compiler is unable to do this, because it simply cannot know where your memory is.

But hey! Don't blame me! I'm not really sure about this behaviour. So let's see if compilers really behave like... me (now I'm going to "hack assembly", to make sure).

P.s. hey, how do you turn your code highlighting on?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!