mbb
mbb

Reputation: 1

Objective-C pointer values

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?

Upvotes: 0

Views: 743

Answers (3)

Blagovest Buyukliev
Blagovest Buyukliev

Reputation: 43508

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.

Upvotes: 0

caf
caf

Reputation: 239041

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.

Upvotes: 0

Lindydancer
Lindydancer

Reputation: 26094

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.

Upvotes: 4

Related Questions