Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clarification of char pointers in C

I'm working through K&R second edition, chapter 5.

On page 87, pointers to character arrays are introduced as:

char *pmessage;
pmessage = "Now is the time";

How does one know that pmessage is a pointer to a character array, and not a pointer to a single character?

To expand, on page 94, the following function is defined:

/* month_name: return the name of the n-th month */
char *month_name(int n)
{
    static char *name[] = {
        "Illegal month",
        "January", "February", "March",
        ...
    };

    return (n < 1 || n > 12) ? name[0] : name[n];
}

If one were simply provided with the function declaration for the above, how could one know whether a single character or a character array is returned?

If one were to assume the return from month_name() is a character array and iterate over it until a NULL is encountered, but the return was in fact a single character then is there not the potential for a segmentation fault?

Could somebody please demonstrate the declaration and assignment of a pointer to a single character vs a character array, their usage with functions and identification of which has been returned?

like image 768
retrodev Avatar asked Mar 14 '14 11:03

retrodev


3 Answers

So what you have is a string literal which is an array of char with static storage duration:

"Now is the time"

in most contexts an array will decay into a pointer to the first element which is what happens here:

pmessage = "Now is the time";

You need to design and document your interface in such a way that you know what to expect for the input and output. There is no run-time information to tell the nature of what is being pointed to.

For example if we look at the man page of strtok it tells us:

Each call to strtok() returns a pointer to a null-terminated string containing the next token.

and so the programmer knows exactly what to expect and deals with the result accordingly.

In the case where you have a pointer to a single char and instead it like a C style string then you will have undefined behavior because you will be accessing memory out of bounds. A segmentation fault is one possibility but being undefined just means the result is unpredictable.

like image 74
Shafik Yaghmour Avatar answered Sep 29 '22 14:09

Shafik Yaghmour


What does

char *pmessage;
pmessage = "Now is the time";  

mean?
char *pmessage; means that you declared pmessage as a pointer to char
pmessage = "Now is the time"; means that pmessage now points to the first character of the string literal Now is the time.

When you return pmessage from a function then a pointer to string literal is returned.
If you will print pmessage with %c specifier then it will print N and if you will print it with %s then it will print the entire string literal.

printf("%c\n", *N);     // 'N' will be printed
printf("%s\n", N);      //  "Now is the time" will be printed 
like image 35
haccks Avatar answered Sep 29 '22 14:09

haccks


Strange as it seems, C trusts the intelligence of the programmer. If I see a function such as:

/* month_name: return the name of the n-th month */
char *month_name(int n)
{
    static char *name[] = {
        "Illegal month",
        "January", "February", "March",
        ...
    };

    return (n < 1 || n > 12) ? name[0] : name[n];
}

I look at the documentation and read that it returns a NUL-terminated string that is a pointer to statically allocated memory. That is enough for me to treat the return value as I should.

If the creator of the function changes the return value in a future release to a different kind of string, they better shout it out loud, change the function name, or make it very clear otherwise it's very bad behavior from their side.

If I on the other hand fail to treat the return value correctly even though it's documented properly, well I wouldn't be so intelligent then and perhaps cut out to be a Java developer.

Lastly, if the function is not documented, find its owner and burn his house.1

1if it's in a library this is released! Don't burn people's house as soon as they start coding a library! ^_^

like image 26
Shahbaz Avatar answered Sep 29 '22 15:09

Shahbaz