C Pointers Questions and Answers

Started by Kalyan, Sep 20, 2008, 11:45 AM

Previous topic - Next topic

Kalyan

C Pointers Questions and Answers

1. I'm trying to declare a pointer and allocate some space for it, but it's not working. What's wrong with this code?

char *p;
*p = malloc(10);
A: The pointer you declared is p, not *p. To make a pointer point somewhere, you just use the name of the pointer:
p = malloc(10);
It's when you're manipulating the pointed-to memory that you use * as an indirection operator:
*p = 'H';

2. Does *p++ increment p, or what it points to?

A: Postfix ++ essentially has higher precedence than the prefix unary operators. Therefore, *p++ is equivalent to *(p++); it increments p, and returns the value which p pointed to before p was incremented. To increment the value pointed to by p, use (*p)++ (or perhaps ++*p, if the order of the side effect doesn't matter).

3. I have a char * pointer that happens to point to some ints, and I want to step it over them. Why doesn't
((int *)p)++;work?

A: In C, a cast operator does not mean "pretend these bits have a different type, and treat them accordingly"; it is a conversion operator, and by definition it yields an rvalue, which cannot be assigned to, or incremented with ++. (It is either an accident or a delibrate but nonstandard extension if a particular compiler accepts expressions such as the above.) Say what you mean: use
p = (char *)((int *)p + 1);
or (since p is a char *) simply
p += sizeof(int);

Whenever possible, you should choose appropriate pointer types in the first place, instead of trying to treat one type as another.

4. I have a function which accepts, and is supposed to initialize, a pointer:

void f(int *ip)
{
static int dummy = 5;
ip = &dummy;
}
But when I call it like this:
int *ip;
f(ip);
the pointer in the caller remains unchanged.

A: Are you sure the function initialized what you thought it did?

Remember that arguments in C are passed by value. The called function altered only the passed copy of the pointer. You'll either want to pass the address of the pointer (the function will end up accepting a pointer-to-a-pointer), or have the function return the pointer.

5. Can I use a void ** pointer as a parameter so that a function can accept a generic pointer by reference?

A: Not portably. There is no generic pointer-to-pointer type in C. void * acts as a generic pointer only because conversions are applied automatically when other pointer types are assigned to and from void *'s; these conversions cannot be performed (the correct underlying pointer type is not known) if an attempt is made to indirect upon a void ** value which points at a pointer type other than void *.

6.I have a function extern int f(int *); which accepts a pointer to an int. How can I pass a constant by reference? A call like f(&5); doesn't seem to work.

A: You can't do this directly. You will have to declare a temporary variable, and then pass its address to the function:
int five = 5;
f(&five);

7. Does C even have "pass by reference"?

A: Not really. Strictly speaking, C always uses pass by value. You can simulate pass by reference yourself, by defining functions which accept pointers and then using the & operator when calling, and the compiler will essentially simulate it for you when you pass an array to a function (by passing a pointer instead). However, C has nothing truly equivalent to formal pass by reference or C++ reference parameters. (On the other hand, function-like preprocessor macros can provide a form of "pass by name".)

8. I've seen different methods used for calling functions via pointers. What's the story?

A: Originally, a pointer to a function had to be "turned into" a "real" function, with the * operator (and an extra pair of parentheses, to keep the precedence straight), before calling:

int r, func(), (*fp)() = func;
r = (*fp)();

It can also be argued that functions are always called via pointers, and that "real" function names always decay implicitly into pointers (in expressions, as they do in initializations;). This reasoning (which is in fact used in the ANSI standard) means that
r = fp();

is legal and works correctly, whether fp is the name of a function or a pointer to one. (The usage has always been unambiguous; there is nothing you ever could have done with a function pointer followed by an argument list except call the function pointed to.) An explicit * is still allowed.