Pointer Usage

M

Marcus Jacobs

Before I am flamed, I did search the FAQ for an answer to the question
that I am about to post. Even with a search of the newsgroup archive,
there are so many subjects about pointers I could search for a long
time and not find an answer to my question.

I am currently integrating the Moller-Trumbore ray/triangle
intersection algorithm
(http://www.ce.chalmers.se/old/staff/tomasm/raytri/raytri.c) into an
existing raytracer. I have basically plagiarized the original code
with some minor modifications to variable names in order integrate it
into the existing raytracer. Below is the source code to the portion
of the source code that I am modifying. The program compiled under
Cygwin using gcc 3.3.3-2. When I run the program, I receive a
"Segmentation Segmentation fault (core dumped)" error. After
recompiling the program using the -ggdb compile option, I executed the
program within gdb in order to find out where the problem is
occurring. At this point, it was determined that the Segmentation
fault occurs at the line that reads:

*u = DOT(tvec, pvec);

Does anyone know if this statement is legal? Moller uses this exact
same code and I am assuming that he has successfully run it. The
reason why I question whether or not this satement is legal is because
I am dereferencing the pointer and setting it value to DOT(tvec,
pvec), since this value is calculated on the fly it has no memory
assigned to it and therefore no address. Am I off base? Is the
original Moller-Trumbore code valid?

Marcus




triangleintersect(o, r) /* compute intersection with polygonal face
*/
OBJREC *o;
register RAY *r;
{
double rdot; /* direction . normal */
double t; /* distance to intersection */
FVECT pisect; /* intersection point */
register FACE *f; /* face record */
register int i;
double *u, *v, *t;
double det, d, inv_det;
double tvec[3], pvec[3], qvec[3], edge1[3], edge2[3];
VSUB(edge1, VERTEX(f,1), VERTEX(f,0));
VSUB(edge2, VERTEX(f,2), VERTEX(f,0));

/* begin calculating determinant - also used to calculate U
parameter */
VCROSS(pvec, r->rdir, edge2);
/* if determinant is near zero, ray lies in plane of triangle */
det = DOT(edge1, pvec);
if (det < FTINY)
return 0;

/* calculate distance from vert0 to ray origin */
VSUB(tvec, r->rorg, VERTEX(f,0));
/* calculate U parameter and test bounds */
*u = DOT(tvec, pvec);
if (*u < 0.0 || *u > det)
return 0;
/* prepare to test V parameter */
VCROSS(qvec, tvec, edge1);
/* calculate V parameter and test bounds */
*v = DOT(r->rdir, qvec) ;
if (*v < 0.0 || *u + *v > det)
return 0;
*t = DOT(edge2,qvec);
inv_det = 1.0/det;
*t *= inv_det;


rdot = -DOT(r->rdir, f->norm);
if (rdot <= FTINY && rdot >= -FTINY) /* ray parallels plane */
t = FHUGE;
//else
// t = (DOT(r->rorg, f->norm) - f->offset) / rdot;
if (t <= FTINY || t >= r->rot) /* not good enough */
return(0);
/* compute intersection */
for (i = 0; i < 3; i++)
pisect = r->rorg + r->rdir* t;
r->rot = t;
VCOPY(r->rop, pisect);
r->rod = rdot;
r->ro = o;
VCOPY(r->ron, f->norm);
r->pert[0] = r->pert[1] = r->pert[2] = 0.0;
r->uv[0] = r->uv[1] = 0.0;
r->rox = NULL;
return(1); /* hit */
 
J

Jack Klein

Before I am flamed, I did search the FAQ for an answer to the question
that I am about to post. Even with a search of the newsgroup archive,
there are so many subjects about pointers I could search for a long
time and not find an answer to my question.

I am currently integrating the Moller-Trumbore ray/triangle
intersection algorithm
(http://www.ce.chalmers.se/old/staff/tomasm/raytri/raytri.c) into an
existing raytracer. I have basically plagiarized the original code
with some minor modifications to variable names in order integrate it
into the existing raytracer. Below is the source code to the portion
of the source code that I am modifying. The program compiled under
Cygwin using gcc 3.3.3-2. When I run the program, I receive a
"Segmentation Segmentation fault (core dumped)" error. After
recompiling the program using the -ggdb compile option, I executed the
program within gdb in order to find out where the problem is
occurring. At this point, it was determined that the Segmentation
fault occurs at the line that reads:

*u = DOT(tvec, pvec);

Does anyone know if this statement is legal? Moller uses this exact
same code and I am assuming that he has successfully run it. The
reason why I question whether or not this satement is legal is because
I am dereferencing the pointer and setting it value to DOT(tvec,
pvec), since this value is calculated on the fly it has no memory
assigned to it and therefore no address. Am I off base? Is the
original Moller-Trumbore code valid?

Marcus




triangleintersect(o, r) /* compute intersection with polygonal face
*/

Prototype style function definitions were added to C 15 years ago.
Why are you still using obsolete code like this?

Also, this code could not have possible compiled. Always copy the
real code from your text editor and paste it as text into the body of
your post.
OBJREC *o;
register RAY *r;
{
double rdot; /* direction . normal */
double t; /* distance to intersection */

Here you define 't' as a double.
FVECT pisect; /* intersection point */
register FACE *f; /* face record */
register int i;
double *u, *v, *t;

Here you define another object with the name 't' in the same scope as
the one above. This can't possibly compile.

'u' is defined as a pointer to double in the line above. Since it is
an automatic variable and not initialized, its value is indeterminate.
It can point to a double, it does not do so now.
double det, d, inv_det;
double tvec[3], pvec[3], qvec[3], edge1[3], edge2[3];
VSUB(edge1, VERTEX(f,1), VERTEX(f,0));
VSUB(edge2, VERTEX(f,2), VERTEX(f,0));

/* begin calculating determinant - also used to calculate U
parameter */
VCROSS(pvec, r->rdir, edge2);
/* if determinant is near zero, ray lies in plane of triangle */
det = DOT(edge1, pvec);
if (det < FTINY)
return 0;

/* calculate distance from vert0 to ray origin */
VSUB(tvec, r->rorg, VERTEX(f,0));
/* calculate U parameter and test bounds */
*u = DOT(tvec, pvec);

Here is the line that you say is causing your problem. You have an
indeterminate pointer to double. It does not point to a double, it is
an uninitialized pointer. Attempting to dereference the pointer to
read or write memory is undefined behavior. There is every reason for
your program to crash. '*u' is not a double and most likely not
memory that you have a right to access.
if (*u < 0.0 || *u > det)
return 0;
/* prepare to test V parameter */
VCROSS(qvec, tvec, edge1);
/* calculate V parameter and test bounds */
*v = DOT(r->rdir, qvec) ;

You'll have the same problem here it you get this far.
if (*v < 0.0 || *u + *v > det)
return 0;
*t = DOT(edge2,qvec);

....and here.
inv_det = 1.0/det;
*t *= inv_det;


rdot = -DOT(r->rdir, f->norm);
if (rdot <= FTINY && rdot >= -FTINY) /* ray parallels plane */
t = FHUGE;
//else
// t = (DOT(r->rorg, f->norm) - f->offset) / rdot;
if (t <= FTINY || t >= r->rot) /* not good enough */

Suddenly, in the two lines above (even though one is commented out),
you are suddenly using 't' like it was a double, not a pointer.
return(0);
/* compute intersection */
for (i = 0; i < 3; i++)
pisect = r->rorg + r->rdir* t;
r->rot = t;
VCOPY(r->rop, pisect);
r->rod = rdot;
r->ro = o;
VCOPY(r->ron, f->norm);
r->pert[0] = r->pert[1] = r->pert[2] = 0.0;
r->uv[0] = r->uv[1] = 0.0;
r->rox = NULL;
return(1); /* hit */


Several places you assign the value of the function/macro DOT to
actual doubles, like 'rdot' and 'det'. Other places you try to assign
the result of whatever twilight zone specified by an indeterminate
pointer, and that's a definite no-no.

Why are 'u', 'v', and 't' defined as pointers to double, and not just
doubles?

This code is frankly unreadable and unmaintainable. Single character
variable names some upper case, pre-ANSI function definitions, and
poor structure make it a nightmare.
 
D

Dag Viken

Jack Klein said:
Before I am flamed, I did search the FAQ for an answer to the question
that I am about to post. Even with a search of the newsgroup archive,
there are so many subjects about pointers I could search for a long
time and not find an answer to my question.

I am currently integrating the Moller-Trumbore ray/triangle
intersection algorithm
(http://www.ce.chalmers.se/old/staff/tomasm/raytri/raytri.c) into an
existing raytracer. I have basically plagiarized the original code
with some minor modifications to variable names in order integrate it
into the existing raytracer. Below is the source code to the portion
of the source code that I am modifying. The program compiled under
Cygwin using gcc 3.3.3-2. When I run the program, I receive a
"Segmentation Segmentation fault (core dumped)" error. After
recompiling the program using the -ggdb compile option, I executed the
program within gdb in order to find out where the problem is
occurring. At this point, it was determined that the Segmentation
fault occurs at the line that reads:

*u = DOT(tvec, pvec);

Does anyone know if this statement is legal? Moller uses this exact
same code and I am assuming that he has successfully run it. The
reason why I question whether or not this satement is legal is because
I am dereferencing the pointer and setting it value to DOT(tvec,
pvec), since this value is calculated on the fly it has no memory
assigned to it and therefore no address. Am I off base? Is the
original Moller-Trumbore code valid?

Marcus




triangleintersect(o, r) /* compute intersection with polygonal face
*/

Prototype style function definitions were added to C 15 years ago.
Why are you still using obsolete code like this?

Also, this code could not have possible compiled. Always copy the
real code from your text editor and paste it as text into the body of
your post.
OBJREC *o;
register RAY *r;
{
double rdot; /* direction . normal */
double t; /* distance to intersection */

Here you define 't' as a double.
FVECT pisect; /* intersection point */
register FACE *f; /* face record */
register int i;
double *u, *v, *t;

Here you define another object with the name 't' in the same scope as
the one above. This can't possibly compile.

'u' is defined as a pointer to double in the line above. Since it is
an automatic variable and not initialized, its value is indeterminate.
It can point to a double, it does not do so now.
double det, d, inv_det;
double tvec[3], pvec[3], qvec[3], edge1[3], edge2[3];
VSUB(edge1, VERTEX(f,1), VERTEX(f,0));
VSUB(edge2, VERTEX(f,2), VERTEX(f,0));

/* begin calculating determinant - also used to calculate U
parameter */
VCROSS(pvec, r->rdir, edge2);
/* if determinant is near zero, ray lies in plane of triangle */
det = DOT(edge1, pvec);
if (det < FTINY)
return 0;

/* calculate distance from vert0 to ray origin */
VSUB(tvec, r->rorg, VERTEX(f,0));
/* calculate U parameter and test bounds */
*u = DOT(tvec, pvec);

Here is the line that you say is causing your problem. You have an
indeterminate pointer to double. It does not point to a double, it is
an uninitialized pointer. Attempting to dereference the pointer to
read or write memory is undefined behavior. There is every reason for
your program to crash. '*u' is not a double and most likely not
memory that you have a right to access.
if (*u < 0.0 || *u > det)
return 0;
/* prepare to test V parameter */
VCROSS(qvec, tvec, edge1);
/* calculate V parameter and test bounds */
*v = DOT(r->rdir, qvec) ;

You'll have the same problem here it you get this far.
if (*v < 0.0 || *u + *v > det)
return 0;
*t = DOT(edge2,qvec);

...and here.
inv_det = 1.0/det;
*t *= inv_det;


rdot = -DOT(r->rdir, f->norm);
if (rdot <= FTINY && rdot >= -FTINY) /* ray parallels plane */
t = FHUGE;
//else
// t = (DOT(r->rorg, f->norm) - f->offset) / rdot;
if (t <= FTINY || t >= r->rot) /* not good enough */

Suddenly, in the two lines above (even though one is commented out),
you are suddenly using 't' like it was a double, not a pointer.
return(0);
/* compute intersection */
for (i = 0; i < 3; i++)
pisect = r->rorg + r->rdir* t;
r->rot = t;
VCOPY(r->rop, pisect);
r->rod = rdot;
r->ro = o;
VCOPY(r->ron, f->norm);
r->pert[0] = r->pert[1] = r->pert[2] = 0.0;
r->uv[0] = r->uv[1] = 0.0;
r->rox = NULL;
return(1); /* hit */


Several places you assign the value of the function/macro DOT to
actual doubles, like 'rdot' and 'det'. Other places you try to assign
the result of whatever twilight zone specified by an indeterminate
pointer, and that's a definite no-no.

Why are 'u', 'v', and 't' defined as pointers to double, and not just
doubles?


I noticed in the original code that u,v, and t were parameters to the
function, presumably to pass back those values to the caller. That not being
the case, these variables should be defined as straight doubles. Note that
the original code at
http://www.ce.chalmers.se/old/staff/tomasm/raytri/raytri.c compiles just
fine. One more point about this code: The pointer 'FACE* f' is never
initialized and will cause more problems.
This code is frankly unreadable and unmaintainable. Single character
variable names some upper case, pre-ANSI function definitions, and
poor structure make it a nightmare.

Well, that's legacy code for you. Just have a look at "Numerical Recipes in
C' (I got edition 2). Who would write maintainable code like that? Yes, I
know several people are questioning some of the advice and algorithms in
that book.

Dag
 
C

CBFalconer

Dag said:
Well, that's legacy code for you. Just have a look at "Numerical
Recipes in C' (I got edition 2). Who would write maintainable
code like that? Yes, I know several people are questioning some
of the advice and algorithms in that book.

Please snip whatever is not germane to your answer. You included
something like 160 totally unnecessary lines, which increases the
transmission and storage loads everywhere.
 
D

Dag Viken

CBFalconer said:
Please snip whatever is not germane to your answer. You included
something like 160 totally unnecessary lines, which increases the
transmission and storage loads everywhere.

Sorry about my bloated email,

Do you have a comment on the issue?

Dag
 
C

CBFalconer

Dag said:
Sorry about my bloated email,

Do you have a comment on the issue?

Thanks. Not really, except that some years ago I developed id2id
(the source of which I lost in a crash). The help screen is:

c:\>id2id
ID2ID (source, target, idpairs, output) Ver. 1.9
usage: ID2ID source target [idpairs]

Replaces identifiers in source, writing to target
If idpairs is not specified on the command line
the file "IDPAIRS." is used. If missing the identifier
list to change is considered empty

idpairs contains a list, in the form:
oldname newname (one per line)
The default input language is Pascal (comment syntax etc)

Initial optional lines in idpairs as follows configure:
$C use C syntax
$ASM use assy syntax
$UPSHIFT upshift all ids on input
$DOWNSHIFT downshift all ids on input
(these must be in upper case)
by default, ID2ID is case sensitive

-------- end help screen ------

I forget what the limitation on id length is. This can be used to
update a whole series of source files in a consistent one-pass
manner, thus installing meaningful names everywhere. It has no
idea of scope. If I have not made it available on my download
page, I can do so (in x86 executable form only).
 
D

Dan Pop

In said:
idea of scope. If I have not made it available on my download
page, I can do so (in x86 executable form only).
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Does this mean that it can be fed to any x86-based system and it will
happily execute it?

Dan
 
C

CBFalconer

Dan said:
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Does this mean that it can be fed to any x86-based system and it
will happily execute it?

Assuming it supplies or simulates a suitable subset of the system
calls of MsDos, yes. Does this mean you want it, as I find it is
not presently mounted?
 
D

Dan Pop

In said:
Assuming it supplies or simulates a suitable subset of the system
calls of MsDos, yes.

There was no mention of MSDOS in your previous post, was it?
Does this mean you want it, as I find it is not presently mounted?

Nope, merely pointing out that the string "x86 executable form" doesn't
make much sense.

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top