Overloaded operator results in null pointer exception when result isn't stored in variable

Started by
9 comments, last by WitchLord 6 years, 4 months ago

Best to describe with some code.

This works:


vec3 diff = s.getPosition() - capturePosition;
float length = length2(diff);
And this throws null pointer exception (Null pointer access):

float length = length2(s.getPosition() - capturePosition);
"vec3" is registered type with overloaded operator "-". Is there any reason why it shouldn't work without storing result in variable?
 
vec3 is registered as (leaving out unrelated stuff)

engine->RegisterObjectType("vec3", sizeof(Vec3Primitive), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_CDAK);

engine->RegisterObjectBehaviour("vec3", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(vec3Constructor), asCALL_CDECL_OBJLAST);

engine->RegisterObjectBehaviour("vec3", asBEHAVE_CONSTRUCT, "void f(float,float,float)", asFUNCTION(vec3Constructor3), asCALL_CDECL_OBJLAST);
engine->RegisterObjectBehaviour("vec3", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(vec3Destructor), asCALL_CDECL_OBJLAST);

engine->RegisterObjectMethod("vec3", "vec3 opSub(const vec3)", asMETHOD(Vec3Primitive,opSub), asCALL_THISCALL);

engine->RegisterGlobalFunction("float length(const vec3)", asFUNCTION(Vec3Primitive::length), asCALL_CDECL);
 

void vec3Constructor(void *memory){
    new(memory) Vec3Primitive();
}

void vec3Constructor3(float x, float y, float z, void *memory){
    new(memory) Vec3Primitive(x, y, z);
}

void vec3Destructor(void *memory){
    ((Vec3Primitive*)memory)->~Vec3Primitive();
}


static float length2(const Vec3Primitive vec3){
   return vec3.x * vec3.x + vec3.y * vec3.y + vec3.z * vec3.z;
}

Vec3Primitive opSub(const Vec3Primitive other){
    return Vec3Primitive(x - other.x, y - other.y, z - other.z);
}
 
I'm using AngelScript version 2.31.1
I've registered this class some time ago and just now added operator overloading, which brought this error. Maybe I am doing something obviously wrong?
 
Advertisement

Did you also register the copy constructor and assignment operator? You specified these as being present (asOBJ_APP_CLASS_CDAK) but you didn't show them. You may be having issues there.

 

Also, you showed the registration for length but not length2, could you show the code for that?

I thought asOBJ_POD takes care or assignment and copies. Or doesn't it mix with asOBJ_APP_CLASS_CDAK? I'll definitely try adding copy constructor and assign op to see if it helps. Is there a reason why it would work when passing variable to lenght2, but not when passing opSub result directly?

length vs length2 - I just me copied wrong line, but they are only differ in function body (sqrt)

Hi valenn,

this has the looks of being a bug in the AngelScript compiler. There shouldn't be any need to store the result of opSub in a variable before passing it on to the next function. I'll investigate it. 

You didn't say where the null pointer exception is coming from? 

 

 

Just a couple of tips (not necessarily related to the bug):

- Instead of using the flags asOBJ_APP_CLASS_CDAK, use the asGetTypeTraits function. That way you don't have to guess what flags to use, e.g. asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<Vec3Primitive>().

- Does your Vec3Primitive really have an explicit destructor that does anything? If not, I suggest skipping the registration of the destructor behaviour. That would be one less call that the script engine has to do.

- Your length() and length2() functions are taking the argument by value. I suggest changing it to take it as const reference (i.e. const vec2 &in). This will allow the compiler to skip making a copy of the vector in some situations, thus improving the efficiency. 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Null pointer is coming from asBC_COPY (as_context.cpp, in ExecuteNext()). Simply adding copy constructor as suggested by Solokiller solved the issue for me. (thanks!)


r = engine->RegisterObjectBehaviour("vec3", asBEHAVE_CONSTRUCT, "void f(const vec3 &in)", asFUNCTION(vec3ConstructorCopy), asCALL_CDECL_OBJLAST); assert( r >= 0 );

void vec3ConstructorCopy(const Vec3Primitive &in, void *memory){
    new(memory) Vec3Primitive(in);
}

Assignment works as expected (making a copy) even without registering copy constructor or assignment operator. If this is indeed bug, and not only missing copy constructor, let me know if I can help somehow

Thank you also for other tips!

Registering the copy constructor will work-around the problem, but it shouldn't be necessary. It is surely a bug in 2.31.1 that is causing this null pointer exception.

 

I haven't been able to reproduce this problem with the latest WIP version from the svn yet. The version you are using is nearly one and a half year old. Would you mind giving the latest WIP version a try to see if you can reproduce the problem in that?

 

float length = length2(s.getPosition() - capturePosition);
	

 

In this code, can you tell me what s is? and how it was declared? Is it a script class? registered type? Is it a global variable, or a local variable?

What is the signature of the method getPosition()? Does it return the vec3 by value or by reference?

The capturePosition variable? is it global, local, or a function argument?

 

 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

I'll try with latest version and let you know.

"s" in previous example is registered type, "getPosition()" returns vec3 by value and "capturePosition" is a member variable of script class. But that probably won't matter, because now I also reproduced it with:


vec3 a = vec3(1.0, 1.0, 1.0);
vec3 b = vec3(0.0, 0.0, 0.0);
float l = length2(b - a);

or


float l = length2(vec3(1.0, 1.0, 1.0) - vec3(0.0, 0.0, 0.0));

 

5 hours ago, valenn said:

vec3 a = vec3(1.0, 1.0, 1.0); vec3 b = vec3(0.0, 0.0, 0.0); float l = length2(b - a);

This was the first I tried when attempting to reproduce the problem. 

I'm pretty sure this bug has already been fixed in the latest WIP version. 

Looking through the change log for throughout the year can see a couple of fixes that may very well have fixed this problem.

 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Yep, it works with latest version without any other changes! Thanks!

Excellent. Thanks for the confirmation.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement