veggies
veggies

Reputation: 23

Why can I dereference a char pointer / string return value from a function?

Say I have function that returns a pointer to a character, or more specifically a string:

char* fun_that_returns_string () {
    char* teststr = "Hello World";
    return teststr;
}

and now I call that function and assign it's return value to a char* somewhere else:

char* s = fun_that_returns_string();

I can then print the returned string and get the "correct" result:

printf("%s\n", s);

Output:

> Hello World

Shouldn't the local value teststr or its address be invalid outside of the function, since it is cleared after returning? Is it undefined behaviour and I was just lucky that is was not overwritten before I printed? If that is the case, what is the correct way to handle returned strings?

Another example: When I use predefined functions like e.g. ctime(3) from time.h which returns a char* and I call the function directly in the arguments of another function

time_t t;
t = time(&t);

foo(ctime(&t));

This function will receive the return value of ctime(), which is a pointer to the first character of the time string, as a copy. So it's kind of the same as above? My understanding is that whatever happened inside ctime() should not be dereferenced any more, unless it was malloc'ed on the heap (but in that case I would have to free it myself)?

My professor used this ctime()-direct-argument-thing in some example code and I just can't wrap my head around it.

Upvotes: 2

Views: 101

Answers (2)

Adrian Mole
Adrian Mole

Reputation: 51894

You are correct in thinking that it is normally wrong for a function to return the address of a local variable, as that variable will 'cease to exist' once the function has ended. However, in your code, you are returning the address of a string literal. In this case, the C Standard guarantees that the data will have static storage:

6.4.5 String Literals


Semantics

6    … The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence.

For your second point regarding the string returned by the ctime function, static storage again comes to the rescue. From cppreference:

Return value

  1. pointer to a static null-terminated character string holding the textual representation of date and time. The string may be shared between asctime and ctime, and may be overwritten on each invocation of any of those functions.

For a description of the various storage classes (including static storage) used in C, here is a nice tutorial.

Upvotes: 2

Emoun
Emoun

Reputation: 2507

You first example is completely legal and works as expected.

The reason is that you are getting the address of a static string. "Hello World" defines an array of characters that are saved in the program binary. It then returns to you an address to that array at runtime. Since the string is part of the program it is always available and its pointer will never become invalid. Whether the function defining the string returns or not is therefore irrelevant to the validity of the pointer.

Upvotes: 1

Related Questions