0

I'm compiling an application using X-Code 3.2.6 (64-bit). The application is compiling against the 10.5 SDK and in 32 Bit Intel Architecture.

I've declared a character array as:

char iptmp[ARRAY_SIZE];

so I'm calling a function thus:

myfunc(&iptmp);

Where myfunc is declared:

void myfunc(char** value)
{
  ...
};

With the intention of loading the character array with the contents of another string with strncpy. When you see what's below you might appreciate why I don't simply do something like: strcpy(iptmp, myfunc()); but here is the problem:

Value of iptmp prior to function call:  0xb0206f5a
Value of *value in function:            0xffffb020

I've tried various things to resolve this problem, but the only thing that seems to stick is to receive a UINT32 value and cast:

myfunc((UINT32) &iptmp);

void myfunc(UINT32 value)
{
  char* target = (char*) value;

  ...
}

This is causing havoc in my code. What is going on with the pointer value?

3
  • @Athabaska: the OP's on the money. iptmp is of type char*, so &iptmp is a char**. EDIT: as far as that's concerned, anyway... Commented Apr 14, 2011 at 11:33
  • 1
    @Mac: That is incorrect. iptmp is of type char [ARRAY_SIZE], which is entirely different to char * (though the former is useable as the latter in some contexts), and &iptmp is consequently of type char (*)[ARRAY_SIZE], which again is entirely different to char ** (and never interchangeable). Commented Apr 14, 2011 at 12:03
  • @caf: I may have been a bit hasty. Right you are! :) Commented Apr 14, 2011 at 12:06

3 Answers 3

4

What happens here is that iptmp is a location in memory. If you write iptmp you will get the address of the aray. However, you will also get the address of it if you write &iptmp. However, you assume that you will get a pointer to a pointer to the array.

The best way to handle this is simply doing:

void myfunc(char * value)
{
  ...
};

The pointer value will point to the array, which you can modify anyway you like.

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

Comments

0

When you derefence *value, you're saying "take the pointer stored in value, and load the bytes at that location as if they were a char *". But the bytes at the location pointed to by value aren't a char * - they're the first bytes of iptmp[] itself (in your case, the first 4 bytes).

The root cause is that you're passing &iptmp, which has type char (*)[ARRAY_SIZE], to a function that expects a char ** parameter. These types are not interchangeable, as you've found. The correct declaration for the function would be:

void myfunc(char (*value)[ARRAY_SIZE])
{
    /* ... */
}

You can then pass &iptmp, and you will find that *value has the value that you expect.

Comments

0

Why not just

void myfunc(char *value)
{
  strncpy(value, ...);
}

and

myfunc(iptmp);

Remember, arrays and pointers in C are not the same things, although you may have heard the opposite many times. An array is an object whose size is equal to its length multiplied by the size of each of its elements, while a pointer is just like a single int but with special semantics.

Hence, the two expressions iptmp and &iptmp yield the same result, namely the starting address of the array. iptmp yields a pointer value for convenience, but that doesn't mean that the object iptmp is a pointer itself.

By attempting to get the address of the address of the array, you really intend to perform &(&iptmp), which is a meaningless, erroneous operation.

3 Comments

Thanks. Getting too close to the problem. In this context what you suggest is OK and works. My tracing is telling me that the value for char* is being passed faithfully too, but this is not the case for char**. So my question still stands.
@mbb: You don't need a pointer to a pointer to do what you want to do. However, if this is really what a pointer to a pointer, then you would have to create a real, physical pointer to point to. as in char iptmp[...]; char * pointer = &iptmp; myfunc(&pointer);.
Thanks. Once again too close to the problem

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.