...
This noncompliant code example declares the variable p
as a pointer to a constant char
with file scope. The value of str
is assigned to p
within the dont_do_this()
function. However, str
has automatic storage duration, so the lifetime of str
ends when the dont_do_this()
function exits.
Code Block | ||||
---|---|---|---|---|
| ||||
const char *p; void dont_do_this(void) { const char str[] = "This will change"; p = str; /* dangerous */ /* ... */ } void innocuous(void) { const char 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 str
, preventing p
from taking on an indeterminate value outside of this_is_OK()
.
Code Block | ||||
---|---|---|---|---|
| ||||
void this_is_OK(void) { const char str[] = "Everything OK"; const char *p = str; /* ... */ } /* p is inaccessible outside the scope of string str */ |
...
If it is necessary for p
to be defined with file scope, it can be set to NULL
before str
is destroyed. This prevents p
from taking on an indeterminate value, although any references to p
must check for NULL
.
Code Block | ||||
---|---|---|---|---|
| ||||
const char *p; void is_this_OK(void) { const char str[] = "Everything OK?"; p = str; /* ... */ p = NULL; } |
...
In this example, the function init_array()
incorrectly returns a pointer to a local stack variable.
Code Block | ||||
---|---|---|---|---|
| ||||
char *init_array(void) { char array[10]; /* Initialize array */ return array; } |
...
Correcting this example depends on the intent of the programmer. If the intent is to modify the value of array
and have that modification persist outside of the scope of init_array()
, the desired behavior can be achieved by declaring array
elsewhere and passing it as an argument to init_array()
.
Code Block | ||||
---|---|---|---|---|
| ||||
void init_array(char array[]) { /* Initialize array */ return; } int main(int argc, char *argv[]) { char array[10]; init_array(array); /* ... */ return 0; } |
...