1

Why don't the print statements in the function match the top level prints?

#include<stdio.h>
#include <stdlib.h>
#include<math.h>

void bar(float **foo)
{
  printf(" &foo[0][0]    %f \n", &foo[0][0]);
}

int main()
{
  float mat[5][5], **ptr;
  mat[0][0] = 3.0f;
  ptr = (float **)mat;
  printf("  mat[0][0]    %f \n",  mat[0][0]);
  printf(" &ptr[0][0]    %f \n", &ptr[0][0]);
  bar(ptr);
}

the results:

 mat[0][0]     3.000000 
 &ptr[0][0]    3.000000 
 &foo[0][0]    -0.005548 
4
  • Why are you using &foo and &ptr? Commented Feb 9, 2012 at 0:09
  • I'm obviously doing this completely wrong... All I'm trying to do is figure out how to pass a 2D float array to my function... Commented Feb 9, 2012 at 0:24
  • Read section 6 of the comp.lang.c FAQ. Commented Feb 9, 2012 at 0:28
  • Do it so: void bar(float foo[5][]) Commented Feb 9, 2012 at 0:28

2 Answers 2

1

You should print pointers using %p. not %f. Also, the cast (float**)mat doesn't make any sense.

When you say &((float**)mat)[0][0], you actually look for a pointer in the address of mat. if pointers are wider than floats, you will read from some other bytes in the stack, and they can changed when you call functions.

Sign up to request clarification or add additional context in comments.

Comments

1

Several others have gotten you for what looks like confusion between mat[0][0] being of type float and &ptr[0][0] being of type float *, but you have another more subtle problem: ARRAYS ARE NOT POINTERS.

Normally arrays are a lot like pointers, but for very subtle reasons, float [][] is not compatible with float ** the way float [] and float * are.

In many contexts (such as being passed to a function), an array decays to a pointer to its first element. Thus, mat decays to &mat[0]. The type of an array T [] decays to a pointer T *, which means that the type mat decays to (and the type of &mat[0]) is float (*)[] - that is, a pointer to an array of fixed size.

Here is the difference between a float * and a float[]:

float *     float[]
+-----+     +-----+-----+
| ptr | --> | 0.0 | 1.0 |
+-----+     +-----+-----+

Now here is the difference between a float ** and a float[][]:

float **    float *[]   float[][]         float (*)[]
+-----+     +-----+     +-----+-----+     +-----+     (imagine this
| ptr | --> | ptr | --> | 0.0 | 1.0 | <-- | ptr |     pointing to
+-----+     +-----+     +-----+-----+     +-----+     the 0.0 cell)
            | ptr | --> | 2.0 | 3.0 |
            +-----+     +-----+-----+

Those types are, from left to right, pointer-to-pointer-to-float, array-of-pointers-to-float, array-of-arrays-of-floats, and pointer-to-array-offloats. The address of &float[0], converted to a float **, gets dereferenced twice as a pointer even though there is only one pointer - the pointer to float[0] (and thus, the rest of the array). Any value you get through this is garbage.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.