Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added "thread" storage duration per C11, and changed "str" to "c_str" in code examples and write up.

An object has a storage duration that determines its lifetime. There are three four storage durations: static, threadautomatic, and allocated.

According to the C Standard, section 6.2.4, paragraph 2 [ISO/IEC 9899:2011],

...

In this noncompliant code sample, the address of local variable c_str is assigned to the variable p, which has file scope. The assignment itself is legal, but it is illegal for c_str to go out of scope while p holds its address, as happens at the end of dont_do_this().

Code Block
bgColor#FFCCCC
langc
const char *p;
void dont_do_this(void) {
    const char c_str[] = "This will change";
    p = c_str; /* dangerous */
    /* ... */
}

void innocuous(void) {
    const char c_str[] = "Surprise, surprise";
}
/* ... */
dont_do_this();
innocuous();
/* p might be pointing to "Surprise, surprise" */

...

In this compliant solution, p is declared with the same scope as c_str, preventing p from taking on an indeterminate value outside of this_is_OK().

Code Block
bgColor#ccccff
langc
void this_is_OK(void) {
    const char c_str[] = "Everything OK";
    const char *p = c_str;
    /* ... */
}
/* p is inaccessible outside the scope of string c_str */

Alternately, both p and c_str could be declared with static scope.

...

If it is necessary for p to be defined with file scope, but c_str with a more limited scope, then p can be set to NULL before c_str is destroyed. This practice prevents p from taking on an indeterminate value, although any references to p must check for NULL.

Code Block
bgColor#ccccff
langc
const char *p;
void is_this_OK(void) {
    const char c_str[] = "Everything OK?";
    p = c_str;
    /* ... */
    p = NULL;
}

...