-1

When I call my calculatePlaneEQ function, it throws me an access violation when I assign values back... I'm rusty on my pointers but it seems that this should work!

float *planeCoefA, *planeCoefB, *planeCoefC, *planeCoefD = NULL;

CALL:

calculatePlaneEQ (<...>, &planeCoefA, &planeCoefB, &planeCoefC, &planeCoefD);

DEF:

void calculatePlaneEQ (<...>, float ** myXnorm, float ** myYnorm, float ** myZnorm, float** myD)
{
    float  xNorm = 1.3;
    float  yNorm = 1.4;
    float  zNorm = 1.5;
    float eqD = 1.6; 

    *(*myXnorm) = xNorm;
    *(*myYnorm) = yNorm;
    *(*myZnorm) = zNorm;
    *(*myD) = eqD;  
}
Littm
  • 4,923
  • 4
  • 30
  • 38
  • 2
    Are these pointers assigned to valid memory locations before passing to the function ? – Mahesh Oct 01 '12 at 20:59
  • 1
    None of your `plane...` pointers have values. – Hot Licks Oct 01 '12 at 21:00
  • @Mahesh: look again, the pointers assignments are in the question (I missed them at first too) – Mooing Duck Oct 01 '12 at 21:00
  • 1
    In the provided code you have not malloc()'d space for the pointers. 0xCCCCCCCC is also a "guard value" for uninitialized memory. – std''OrgnlDave Oct 01 '12 at 21:01
  • 1
    @MooingDuck still missing the assignments...other than to NULL... – std''OrgnlDave Oct 01 '12 at 21:02
  • @MooingDuck I meant what @std"OrgnlDave said. – Mahesh Oct 01 '12 at 21:03
  • 2
    Consider wrapping all these variables into a single struct, this will increase readability. Also you will be able to return the struct instead of messing around with pointers. – user1708860 Oct 01 '12 at 21:06
  • See http://stackoverflow.com/questions/370195/when-and-why-will-an-os-initialise-memory-to-0xcd-0xdd-etc-on-malloc-free-new for a comprehensive list of MSVC's debug memory fill values. This may give you a leg up in the future on problems like this. – Michael Burr Oct 01 '12 at 21:22

4 Answers4

8

It should be:

float planeCoefA, planeCoefB, planeCoefC, planeCoefD;

CALL:

calculatePlaneEQ (<...>, &planeCoefA, &planeCoefB, &planeCoefC, &planeCoefD);

DEF:

void calculatePlaneEQ (<...>, float * myXnorm, float * myYnorm, float * myZnorm, float * myD)
{

    float  xNorm = 1.3;
    float  yNorm = 1.4;
    float  zNorm = 1.5;
    float eqD = 1.6; 

    *myXnorm = xNorm;
    *myYnorm = yNorm;
    *myZnorm = zNorm;
    *myD = eqD;
}

Better still, use references rather than pointers:

CALL:

calculatePlaneEQ (<...>, planeCoefA, planeCoefB, planeCoefC, planeCoefD);

DEF:

void calculatePlaneEQ (<...>, float &myXnorm, float &myYnorm, float &myZnorm, float &myD)
{

    float  xNorm = 1.3;
    float  yNorm = 1.4;
    float  zNorm = 1.5;
    float eqD = 1.6; 

    myXnorm = xNorm;
    myYnorm = yNorm;
    myZnorm = zNorm;
    myD = eqD;
}

This is more idiomatic C++ than the C-style use of pointers, and is less error-prone.

Paul R
  • 208,748
  • 37
  • 389
  • 560
1
float *planeCoefA, *planeCoefB, *planeCoefC, *planeCoefD = NULL;

You have not initialized any of your pointers. planeCoefA, planeCoefB, and planeCoefC will have random values. Only planeCoefD is assigned NULL, but that's not valid to write to either.

However, you proceed to just assign values to those memory locations anyway. This is undefined behavior. Pointers are variables and their values are memory addresses. However, they do not automatically point at valid memory; they need to be initialized.

float planeCoefA = 0, planeCoefB = 0, planeCoefC = 0, planeCoefD = 0;

// ...

void calculatePlaneEQ (<...>, float *myXnorm, float *myYnorm, float *myZnorm, float* myD)

The only reason to add another level of indirection (i.e., float** v float*) is if you need to modify the argument such that it can be seen by the caller (because, remember; you're passing these arguments by value). You simply need to write to the memory location that the pointers refer to, so a single pointer is sufficient.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • To be a little more specific, you have allocated space for the pointers, but when you de-dereference them in the assignment, eg, *(*myXnorm) = xNorm; there is no memory allocated to actually put the bits in. – David Oct 01 '12 at 21:03
  • @David: No, space is already allocated *for the pointers*. Their value needs to be initialized to a valid memory address. – Ed S. Oct 01 '12 at 21:04
1

Seems you are doing one level of indirection too much.

float planeCoefA, planeCoefB, planeCoefC, planeCoefD;

call

calculatePlaneEQ (<...>, &planeCoefA, &planeCoefB, &planeCoefC, &planeCoefD);

and

void calculatePlaneEQ (<...>, float * myXnorm, float * myYnorm, float * myZnorm, float* myD)
{
 ...
  *myXnorm = 12.1f;
 ...
AndersK
  • 35,813
  • 6
  • 60
  • 86
0

You can always work with genuine floats and references to make things simpler for yourself and others.

float planeCoefA = 0.0;
float planeCoefB = 0.0;
float planeCoefC = 0.0;
float planeCoefD = 0.0;

CALL: calculatePlaneEQ (<...>, planeCoefA, planeCoefB, planeCoefC, planeCoefD);

DEF:

void calculatePlaneEQ (<...>, float & myXnorm, float & myYnorm, float & myZnorm, float & myD)
{

    myXNorm = 1.3;
    myYNorm = 1.4;
    myZNorm = 1.5;
    myD = 1.6; 

}

If you prefer, for some reason, to use pointers, then you can use float pointers in the function signature:

void calculatePlaneEQ (<...>, float * myXnorm, float * myYnorm, float * myZnorm, float * myD)

in which case you would then precede each variable name by an asterisk in the body of the function:

*myXNorm = 1.3;

However, you would then run the risk of being passed invalid pointers.

Alan
  • 1,889
  • 2
  • 18
  • 30