How to Continue Running in API after Memory Violation Error at Line 107 of Memory.h

How to Continue Running in API after Memory Violation Error at Line 107 of Memory.h

tperam
Advocate Advocate
2,507 Views
12 Replies
Message 1 of 13

How to Continue Running in API after Memory Violation Error at Line 107 of Memory.h

tperam
Advocate
Advocate

How to Continue Running in API after Memory Violation Error at Line 107 of Memory.h with Abort, Debug, Ignore Buttons?

 

When there is Memory Violation Error at Line 107 of Memory.h with Abort, Debug, Ignore Buttons, when I select one of the four solutions starting from 0 and incrementing by 1 to check for Validity of the solution one by one and eliminate invalid solutions.

 

When I click Ignore, the program stops running and blocking me from trying all the possible four solutions by incrementing by 1, covering solution item(0) to item(3).

 

How can I continue running in API from where it left off?

 

I tried inserting '#define NDebug' Statement before Include Core.all before compiling, as below.

 

#define NDEBUG
#include <Core/CoreAll.h>
#include <Fusion/FusionAll.h>
#include <CAM/CAMAll.h>

 

Then the Program did not diplay the Memory Violation Error, but stopped running.

 

How can I continue running in API from where it left off?

 

Regards,
Thurai

0 Likes
Accepted solutions (2)
2,508 Views
12 Replies
Replies (12)
Message 2 of 13

KrisKaplan
Autodesk
Autodesk

By 'memory violation error', I assume you are getting an access violation exception. And this line (memory.h(107)) would be adsk::core::Ptr<T>::operator->(). This is the inline smart pointer class' dereference operator.

 

An access violation on this line should mean an problem reading memory at "&Ptr<T>::ptr_", and that should mean that the address of the Ptr<T> variable is bad. Since these smart pointers are most commonly on the call stack as a local variable, this could mean corruption of the call stack, and there is not really an easy or safe way to continue at this point. You would need to identify where the original memory corruption occurred and handle it there somehow.

 

The other possibility is if this is happening to a Ptr variable that you had referenced in another container (a class or a std container). If that is the case, then you need to determine what happened to the memory of that container.

 

Kris



Kris Kaplan
0 Likes
Message 3 of 13

tperam
Advocate
Advocate

 

Is there a way to find out before using the Item(Iterated Item Number Ranging from 0 to 3),  so that I can skip that particular Item Number in question, if an Item(Iterated Item Number) will lead to a Pointer Error?

 

Relevant steps of my  C++ Code is as below.

 

IntersectionObjColl = IntersectPlanePhi->intersectWithSurface(surface[0]);
if (!IntersectionObjColl)
return false;

 

Ptr<Curve3D> curve3D;


TryNextItemNumber:
curve3D = IntersectionObjColl->item(Item);
if(!curve3D)

return false;

 

else if(item < 3)

{

 Item++;

 goto TryNextItemNumber;

}

 

Thanks Kris.

Thurai

0 Likes
Message 4 of 13

KrisKaplan
Autodesk
Autodesk

I'm not noticing anything obvious in your snippet, but specifically which 'operator->()' call is hitting the exception? In this code, the only one I see is the call to 'ObjectCollection::item'. But from your description, I assume it is happening later when you attempt to use the item, so I would assume in this case it is the 'curve3D' variable.

 

If it is on the dereference of the curve3D variable immediately after it is returned from the 'item' method, then as mentioned, I would most likely suspect that there was a stack corruption (not specifically related to this item, but caused somewhere else in your code and it just eventually crashes at this point).

 

You should note that the pointer should have been good when it was returned from the 'item' method, because that is assigning it into a Ptr with a different template type, so it will dereference the raw pointer to query for that type, and do some reference counting. So it appears that the pointer is going bad after this point. If you set a memory address breakpoint on that Ptr's ptr_ variable, you should break at the point it gets stomped on (if that is in fact what is happening).

 

Also note that plane surface intersection isn't limited to return a Curve3D. It can also result in a Point3D (e.g. when tangent to a point on the surface).

 

If it is reproducible with a simple sample, then please send the files and the simplified script and we can look at it. It looks like in this case, it should only take a plane, the surface you are intersecting with, and this looping code if it is specific to the surface geometry.

 

Kris



Kris Kaplan
0 Likes
Message 5 of 13

tperam
Advocate
Advocate

Hi Kris,
as you suspected the violation is occuring at the following line with M Ranging from 0 to 2.

if(!(y = IntersectionPts[M]->y()) )
{//if(!y)
Some code here
}//if(!y)

The relevant code routine is given below.

Thanks Kris.

/////////////////////////////////////////////////////
// Arc3PtsByIntersectWithSurfaceCurve() //////////////////////////////////////////////////////////////////////////////////////////
bool Arc3PtsByIntersectWithSurfaceCurve(Common &Com, VTOLMIDBODY &vtolmidbody, BULKHEAD &bulkhead, VTOLBODY &VTOLBody, unsigned int JPhi, unsigned int Ifr, unsigned int J, unsigned int K, unsigned int IzBulk)
// Create three sketch points
{//

bulkhead.msg = " In Arc3PtsByIntersectWithSurfaceCurve( ";
if(Com.IDebug == 10) ui->messageBox(bulkhead.msg);
unsigned int If;
if(Ifr == 0) {If = 0;} /* The Front Junction Arc */
else if (Ifr == 1) {If = 1;} /* The Rear Junction Arc */
else if (Ifr == 2 && abs(VTOLBody.zValueOfPlaneBulk[Ifr][0][0]) < 500.0 ) {If = 0;} /* The Front Junction Arc */
else {If = 1;} /* VTOLBody.IRivetSubRegion[Ifr] = 2, The Front Junction Arc */


unsigned int M, Item;

/////////////////////////////////////////////////////////////////

Ptr<Vector3D> NormalPhi;
double NormPhiy = - sin(vtolmidbody.Phi[JPhi]);

TryPlusNormPhi:
Item = 0;

NormalPhi = adsk::core::Vector3D::create(cos(vtolmidbody.Phi[JPhi]), NormPhiy, 0);
if(!NormalPhi)
return false;

 

Ptr<Plane> IntersectPlanePhi;

IntersectPlanePhi = adsk::core::Plane::create(adsk::core::Point3D::create(1.0e-3, 0, 0), NormalPhi);
if (!IntersectPlanePhi)
return false;


Ptr<ObjectCollection> IntersectionObjColl = adsk::core::ObjectCollection::create();
if(!IntersectionObjColl)
return false;

if(Com.IDebug == 10) ui->messageBox(" After IntersectionPtsObjColl ");


Ptr<BRepFaces> faces = VTOLBody.Body->faces();

if(Com.IDebug == 10) ui->messageBox(" After faces ");

unsigned int faceCount = faces->count();

bulkhead.msg = " faceCount ";
sprintf_s (bulkhead.dStr, "%d", faceCount); // %d makes the result be a decimal integer
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 10) ui->messageBox(bulkhead.msg);

//Debug
fprintf(Com.out," \n\n faceCount = %4d \n",
faceCount);

// 2 Faces: Outer Curved, Inner
Ptr<BRepFace> face[2];

/* Get the Inner and Outer faces */
face[0] = faces->item(0);
if(!face[0])
return false;

if(Com.IDebug == 10) ui->messageBox(" After face[0] ");

// Get the value of the property.
Ptr<Surface> surface[4];

surface[0] = face[0]->geometry();
if(!surface[0])
return false;

if(Com.IDebug == 10) ui->messageBox(" After surface[0] ");


IntersectionObjColl = IntersectPlanePhi->intersectWithSurface(surface[0]);
if (!IntersectionObjColl)
return false;

if(Com.IDebug == 11) ui->messageBox(" After intersectWithSurface() face 0 ");

unsigned int CountObjectsColl = IntersectionObjColl->count();

bulkhead.msg = " CountObjectsColl = ";
bulkhead.msg += " ";
sprintf_s (bulkhead.dStr, "%d", CountObjectsColl ); // %d makes the result be a decimal integer
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 12) ui->messageBox(bulkhead.msg);

fprintf(Com.out," \n\n CountObjectsColl = %4d \n\n", CountObjectsColl);

Ptr<Base> base = IntersectionObjColl->item(0);

bulkhead.msg = " base = ";
bulkhead.msg += " ";
sprintf_s (bulkhead.dStr, "%d", base );
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 10) ui->messageBox(bulkhead.msg);

string objectType = IntersectionObjColl->objectType();

bulkhead.msg = " objectType = ";
bulkhead.msg += " ";
sprintf_s (bulkhead.dStr, "%s", objectType );
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 10) ui->messageBox(bulkhead.msg);

Ptr<Curve3D> curve3D;


TryNextItemNumber:
curve3D = IntersectionObjColl->item(Item);
if(!curve3D)
{//if(!curve3D)
// get error message
std::string errorMessage;
int errorCode = app->getLastError(&errorMessage);
if (GenericErrors::Ok != errorCode)
{//
ui->messageBox(errorMessage);
fprintf(Com.out," \n\n errorCode = %4d, errorMessage = %20s \n\n", errorCode, errorMessage);
}//

if(Item < CountObjectsColl - 1)
{//if(Item < CountObjectsColl - 1)
Item++;

bulkhead.msg = " Item = ";
bulkhead.msg += " ";
sprintf_s (bulkhead.dStr, "%d", Item);
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 12) ui->messageBox(bulkhead.msg);

fprintf(Com.out," \n\n Item = %4d \n\n", Item);

goto TryNextItemNumber;
}//if(Item < CountObjectsColl - 1)

else {goto Continue;}
}//if(!curve3D)


Continue:

bulkhead.msg = " Item = ";
bulkhead.msg += " ";
sprintf_s (bulkhead.dStr, "%d", Item);
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 12) ui->messageBox(bulkhead.msg);

fprintf(Com.out," \n\n Item = %4d \n\n", Item);


if(Com.IDebug == 12) ui->messageBox(" After IntersectionObjColl->item(); ");

// Get the value of the property.
string CurveType = curve3D->objectType();

//ui->messageBox(" After CurveType = sketchCurve->objectType(); ");

bulkhead.msg = " CurveType = ";
bulkhead.msg += " ";
sprintf_s (bulkhead.dStr, "%s", CurveType );
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 10) ui->messageBox(bulkhead.msg);


/* Create an xz Plane with y Offset */
Ptr<Vector3D> normalxy = adsk::core::Vector3D::create(0, 0, 1);
if(!normalxy)
return false;


Ptr<ObjectCollection> IntersectionPtsObjColl = adsk::core::ObjectCollection::create();
if(!IntersectionPtsObjColl)
return false;


Ptr<Point3D> IntersectionPts[3];

for(M = 0; M <= 2; M++)
{//M
zValueOfPlaneBulk(Com, vtolmidbody, VTOLBody, JPhi, Ifr, IzBulk, M);
bulkhead.zC[J][M] = VTOLBody.zValueOfPlaneBulk[Ifr][IzBulk][M];

//Debug
fprintf(Com.out," \n\n M = %4d, zC[J][M] = %10.3e \n",
M, bulkhead.zC[J][M]);


bulkhead.msg = " M = ";
bulkhead.msg += " ";
sprintf_s (bulkhead.dStr, "%d", M);
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 11) ui->messageBox(bulkhead.msg);


bulkhead.msg = " zC[J][M] = ";
bulkhead.msg += " ";
sprintf_s (bulkhead.dStr, "%f", bulkhead.zC[J][M] );
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 11) ui->messageBox(bulkhead.msg);


Ptr<Plane> xzPlane = adsk::core::Plane::create(adsk::core::Point3D::create(0, 0, bulkhead.zC[J][M]), normalxy);
if (!xzPlane)
return false;


/* Dummy Initialize */
IntersectionPts[M] = adsk::core::Point3D::create(0, 0, 0);

IntersectionPtsObjColl = xzPlane->intersectWithCurve(curve3D);
if (!IntersectionPtsObjColl)
return false;


IntersectionPts[M] = IntersectionPtsObjColl->item(0);


if(Com.IDebug == 12) ui->messageBox(" After IntersectionPts ");

double x, y, z;

fprintf(Com.out," \n\n After IntersectionPts \n\n");

if(!(y = IntersectionPts[M]->y()) )
{//if(!y)
// get error message
std::string errorMessage;
int errorCode = app->getLastError(&errorMessage);
if (GenericErrors::Ok != errorCode)
{//
ui->messageBox(errorMessage);
fprintf(Com.out," \n\n errorCode = %4d, errorMessage = %20s \n\n", errorCode, errorMessage);
}//

if(Item < CountObjectsColl - 1)
{//if
Item++;
goto TryNextItemNumber;
}//if

else
{//else
NormPhiy = - NormPhiy;
goto TryPlusNormPhi;
}//else
}//if(!y)

else if( (JPhi < 6 && y < 0.0) || (JPhi > 6 && y > 0.0) && (Item < CountObjectsColl - 1) )
{//else if

bulkhead.msg = " y = ";
bulkhead.msg += " ";
sprintf_s ( bulkhead.dStr, "%f", y ); // %d makes the result be a decimal integer
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 12) ui->messageBox(bulkhead.msg);

Item++;
goto TryNextItemNumber;
}//else if


if(Com.IDebug == 12)
{ bulkhead.msg = " Item = ";
bulkhead.msg += " ";
sprintf_s ( bulkhead.dStr, "%f", Item ); // %d makes the result be a decimal integer
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 12) ui->messageBox(bulkhead.msg);
}

fprintf(Com.out," \n\n Item = %4d \n\n", Item);

y = IntersectionPts[M]->y();
bulkhead.yC[J][M] = y;
z = bulkhead.zC[J][M];

bulkhead.xC[J][M] = x = IntersectionPts[M]->x();

if(bulkhead.xC[J][M] < 0.0) { bulkhead.xC[J][M] = x = -x;}

bulkhead.msg = " x = ";
bulkhead.msg += " ";
sprintf_s ( bulkhead.dStr, "%f", x ); // %d makes the result be a decimal integer
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 12) ui->messageBox(bulkhead.msg);

bulkhead.msg = " y = ";
bulkhead.msg += " ";
sprintf_s ( bulkhead.dStr, "%f", y ); // %d makes the result be a decimal integer
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 12) ui->messageBox(bulkhead.msg);

bulkhead.msg = " z = ";
bulkhead.msg += " ";
sprintf_s ( bulkhead.dStr, "%f", z ); // %d makes the result be a decimal integer
bulkhead.msg += bulkhead.dStr;
bulkhead.msg += " ";
if(Com.IDebug == 12) ui->messageBox(bulkhead.msg);


if(CurveType == "Line3D")
if(Com.IDebug == 11) ui->messageBox(" CurveType is SketchLine ");

else if(CurveType == "Arc3D")
if(Com.IDebug == 11) ui->messageBox(" CurveType is SketchArc ");

else
if(Com.IDebug == 11) ui->messageBox(" CurveType is None of the Above ");

fprintf(Com.out," \n\n In Construction Plane: J = %4d, M = %4d, CountObjectsColl = %4d, Item = %4d, x = %10.3e, y = %10.3e, z = %10.3e, xC[M] = %10.3e, yC[M] = %10.3e, zC[M] = %10.3e \n",
J, M, CountObjectsColl, Item, x, y, z, bulkhead.xC[J][M], bulkhead.yC[J][M], bulkhead.zC[J][M]);

}//M

 

bulkhead.Points[Ifr][IzBulk][0][0] = bulkhead.zC[0][1] + bulkhead.xC[0][1]; bulkhead.Points[Ifr][IzBulk][0][1] = bulkhead.yC[0][1]; bulkhead.Points[Ifr][IzBulk][0][2] = 0.0;

double dx1, dx11;
double dy1, dy11;
double dr1, dr11;
double Sign;

dx1 = bulkhead.xC[0][0] - bulkhead.xC[0][1];
dx11 = bulkhead.xC[0][2] - bulkhead.xC[0][1];

dy1 = bulkhead.yC[0][0] - bulkhead.yC[0][1];
dy11 = bulkhead.yC[0][2] - bulkhead.yC[0][1];

dr1 = sqrt(dx1 * dx1 + dy1 * dy1);
dr11 = sqrt(dx11 * dx11 + dy11 * dy11);

fprintf(Com.out,"\n dx1 = %10.3e , dy1 = %10.3e , dx11 = %10.3e , dy11 = %10.3e \n",
dx1, dy1, dx11, dy11);


if(JPhi <= 6) {Sign = 1.0;} else {Sign = - 1.0;}
bulkhead.Points[Ifr][IzBulk][1][0] = bulkhead.zC[0][0] + bulkhead.xC[0][1]; bulkhead.Points[Ifr][IzBulk][1][1] = bulkhead.yC[0][1] - Sign * dr1 * (cos(vtolmidbody.Phi[JPhi]) + sin(vtolmidbody.Phi[JPhi]) ); bulkhead.Points[Ifr][IzBulk][1][2] = 0.0;

bulkhead.Points[Ifr][IzBulk][11][0] = bulkhead.zC[0][2] + bulkhead.xC[0][1]; bulkhead.Points[Ifr][IzBulk][11][1] = bulkhead.yC[0][1] + Sign * dr11 * (cos(vtolmidbody.Phi[JPhi]) + sin(vtolmidbody.Phi[JPhi]) ) /* yC[0][2] - yC[0][1] */ ; bulkhead.Points[Ifr][IzBulk][1][2] = 0.0;

/* Avoid Almost a Straight Line and Hanging up in Drawing Arc3Pts */
if(abs(bulkhead.Points[Ifr][IzBulk][1][1] - bulkhead.Points[Ifr][IzBulk][0][1]) < 1.0e-3)
{//if
bulkhead.Points[Ifr][IzBulk][1][1] = bulkhead.Points[Ifr][IzBulk][1][1] - 1.0e-3;
bulkhead.Points[Ifr][IzBulk][11][1] = bulkhead.Points[Ifr][IzBulk][11][1] - 1.0e-3;
}//if

bulkhead.Points[Ifr][IzBulk][2][0] = bulkhead.Points[Ifr][IzBulk][1][0]; bulkhead.Points[Ifr][IzBulk][2][1] = bulkhead.Points[Ifr][IzBulk][1][1] - vtolmidbody.XSectnTh; bulkhead.Points[Ifr][IzBulk][2][2] = 0.0;
bulkhead.Points[Ifr][IzBulk][9][0] = bulkhead.Points[Ifr][IzBulk][0][0]; bulkhead.Points[Ifr][IzBulk][9][1] = bulkhead.Points[Ifr][IzBulk][0][1] - vtolmidbody.XSectnTh; bulkhead.Points[Ifr][IzBulk][9][2] = 0.0;
bulkhead.Points[Ifr][IzBulk][10][0] = bulkhead.Points[Ifr][IzBulk][11][0]; bulkhead.Points[Ifr][IzBulk][10][1] = bulkhead.Points[Ifr][IzBulk][11][1] - vtolmidbody.XSectnTh; bulkhead.Points[Ifr][IzBulk][2][2] = 0.0;

bulkhead.Points[Ifr][IzBulk][3][0] = bulkhead.Points[Ifr][IzBulk][9][0] - bulkhead.ISignX * vtolmidbody.XSectnTh; bulkhead.Points[Ifr][IzBulk][3][1] = bulkhead.Points[Ifr][IzBulk][9][1] /*- vtolmidbody.XSectnTh */; bulkhead.Points[Ifr][IzBulk][3][2] = 0.0;
bulkhead.Points[Ifr][IzBulk][12][0] = bulkhead.Points[Ifr][IzBulk][0][0]; bulkhead.Points[Ifr][IzBulk][12][1] = bulkhead.Points[Ifr][IzBulk][0][1] - vtolmidbody.XSectnTh; bulkhead.Points[Ifr][IzBulk][12][2] = 0.0;

/* if(JPhi == 6, the Three ArcPts are Almost in a Straight Line, and Fusion 360 is Either Hanging Up or Not Drwaing the Arc3Pts. So add a little Offset for the Mid Point of both Arcs */
if(JPhi == 6)
{//
bulkhead.Points[Ifr][IzBulk][0][0] = bulkhead.zC[0][1] + bulkhead.xC[0][1]; bulkhead.Points[Ifr][IzBulk][0][1] = bulkhead.yC[0][1] + 1.0e-4; bulkhead.Points[Ifr][IzBulk][0][2] = 0.0;
bulkhead.Points[Ifr][IzBulk][9][0] = bulkhead.Points[Ifr][IzBulk][0][0]; bulkhead.Points[Ifr][IzBulk][9][1] = bulkhead.Points[Ifr][IzBulk][0][1] - vtolmidbody.XSectnTh + 1.0e-4; bulkhead.Points[Ifr][IzBulk][9][2] = 0.0;
}//


if(Com.IDebug == 12) ui->messageBox(" After Points[Ifr][IzBulk][12][0] ");

//Debug
fprintf(Com.out," \n\n After Points[Ifr][IzBulk][12][0] \n");

return true;

}// end Arc3PtsByIntersectWithSurfaceCurve() ///
// End Arc3PtsByIntersectWithSurfaceCurve() //////////////////////////////////////////////////////////////////////////////////////////

 

I have attached the file.

 

Thanks Kris

0 Likes
Message 6 of 13

KrisKaplan
Autodesk
Autodesk

I'm not seeing anything obvious in there. The only thing might be that you should check the size of IntersectionPtsObjColl before assuming that it has an item(0). If the plane and curve do not intersect, I would expect this to return an empty collection, so item(0) should return null, so the "IntersectionPts[M]->y()" would raise an exception. But if that was the case, it would be the C++ runtime exception we throw from the Ptr-> implementation, not an access violation. But if that is what's happening, then you could just add a null check (if (!IntersectionPts[M])...), or add a try/catch block around this code.

 

If that is not what this is, then I would need a simplified code sample with simplified geometry data to reproduce this to help further. (Not a full app with a big data set, but something like one plane definition, one curve definition, and the failing intersection code between them.)

 

Kris



Kris Kaplan
0 Likes
Message 7 of 13

tperam
Advocate
Advocate

Hi Kris,

 

As per Fusion 360 documentation C++ Specific Issues Says: " In the C++ implementation of the Fusion 360 API, all errors are reported through error codes. There are not asserts fired so a try catch statement will not work."

 

This does not allow using try and catch to catch exceptions.

 

Anyway, I will see if I can omit irrelevant parts of the code and reduce to a minimum to recreate the error.

 

Thanks for your help Kris.

 

Thurai

0 Likes
Message 8 of 13

KrisKaplan
Autodesk
Autodesk

Thurai,

 

Note that line about exceptions propagated out of the API: In languages like Python, they are raised as exceptions. But in C++ we do not raise these errors as exceptions to allow for 'return value, check last error' type error handling.

 

However, this does not apply to null pointer dereferences on your side of the API. An API like 'Collection.item' will return a null pointer on something like an index out of range error. The 'last error' will be set, but if your code dereference the Ptr containing the null pointer, it will raise an exception. So you would either need to check the pointer for null, check for the last error, or wrap it in a try catch block (I would recommend just checking the pointer for 'false-ness').

 

And for a line of code like:

Ptr<adsk::core::Curve3D> curve = planeSurfaceIntersections->item(0);

ObjectCollection::item returns a Ptr<Base>, but you are assigning it to a Ptr<Curve3D>. This has to perform a client side call to query<Curve3D>. So in the case that it really returns a Ptr<Point3D>, that query<>() will fail, leaving the 'curve' variable with a null pointer. If you do not check for that null in your code, the dereference will trigger a client side access violation. This has nothing to do with the API throwing an exceptions on errors. This is purely client side. And if you want to catch client side errors (in either interface queries, or missing error handling), then you could add exception handling.

 

Kris



Kris Kaplan
Message 9 of 13

tperam
Advocate
Advocate

Hi Chris,

             

(1) What are the code lines in C++ to Check for Null Pointer in my subroutine?

 

I assumed the Statements below, check for errors including Null Pointer Error.

 

IntersectionPts[M] = IntersectionPtsObjColl->item(0);

if(!(y = IntersectionPts[M]->y()) )

 

(2) How can I determin if the Intersection of a surface with a plane object type is Curve3D or  a Point3D in the form of C++ code lines?

 

Thanks Kris.

 

Moorthy

 

 

 

0 Likes
Message 10 of 13

KrisKaplan
Autodesk
Autodesk
Accepted solution

Moorthy,

 

Please refer to the C++ Specific Issues in the User's Manual, specifically the 'Handling Errors' and 'Object Types and Casting'. It should specifically address your questions. But basically:

 

1. To check if a Ptr is null, just check the Ptr for a falsy bool value. E.g.

Ptr<Curve3D> curve = curves.item(i);
if (!curve) ...

And no, in those two lines of code, you are not checking the return type of the 'item' method call. In the 'if' condition, you are dereferencing 'IntersectionPts[M]' without ever checking it for null. The 'if' condition is just check if the call to the 'y' property method returned a zero value. But if IntersectionPts[M] contained a nullptr (either because the collection was empty, or did not contain a Point3D type at index 0), the the dereference to call the 'y' method will throw a runtime exception (that would have to be caught and handled if you do not choose to check the pointer value first).

 

2. Refer to the 'Object Types and Casting' section. But basically, you could just try to cast the object to the desired type and check if it succeeded:

Ptr<Base> obj = curvesOrPts->item(i);
if (Ptr<Point3D> pt(obj)) ...
else if (Ptr<Curve3D> curve(obj)) ...

Or you could call the 'objectType' method and switch behavior based on the actual object type. (But switching on objectType is more cumbersome when dealing with polymorphic types. It's usually easier to just try casting to the type you desire as above.)

 

Kris



Kris Kaplan
0 Likes
Message 11 of 13

tperam
Advocate
Advocate
Accepted solution

Hi Kris,
Based on your input I added the following lines of code to check for the count and it worked Okay, skipped over the invalid item number without causing an access violation error as before.

 

////////////////////////////////////////////////
unsigned int CountPtsObjectsColl = IntersectionPtsObjColl->count();

if(CountPtsObjectsColl == 0)
{//if(CountPtsObjectsColl == 0

if(Item < CountObjectsColl - 1)
{//if
Item++;
goto TryNextItemNumber;
}//if

}//if(CountPtsObjectsColl == 0
/////////////////////////

 

But Still I would like the lines of code

(1) to check for Null of

 

y = IntersectionPts[M]->y();

 

(2) to Catch an Exception in this case.

 

Thanks for your help. It works now.

 

Thurai Moorthy

0 Likes
Message 12 of 13

KrisKaplan
Autodesk
Autodesk

Moorthy,

 

"But Still I would like the lines of code

(1) to check for Null of"

 

if (IntersectionPts[M])
  y = IntersectionPts[M]->y();

 

"(2) to Catch an Exception in this case."

 

try {
  y = IntersectionPts[M]->y();
} catch(const std::exception& e) {
  ...
}

 

Kris



Kris Kaplan
Message 13 of 13

tperam
Advocate
Advocate
Hi Kris,
Thanks for your response.

Thurai Moorthy
0 Likes