...
In this noncompliant code sample, the address of local variable str
is assigned to the variable p
, which has file scope. The assignment itself is legal, but it is illegal for str
to go out of scope while p
holds its address, as happens at the end of dont_do_this
()
.
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, but str
with a more limited scope, then p
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 noncompliant code sample, the function init_array
()
returns a pointer to a local stack variable, which could be accessed by the caller.
Code Block | ||||
---|---|---|---|---|
| ||||
char *init_array(void) { char array[10]; /* Initialize array */ return array; } |
...
The solution, in this case, 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; } |
...
In this noncompliant code sample, the function squirrel_away()
stores a pointer to local stack variable local
into a location pointed to by function parameter ptr_param
. Since it an be assumed that the pointer variable to which ptr_param
points remains alive upon squirrel_away()
's return, it is illegal for local
to go out of scope.
Code Block | ||||
---|---|---|---|---|
| ||||
void squirrel_away(char **ptr_param) { char local[10]; /* Initialize array */ *ptr_param = local; } void rodent() { char *ptr; squirrel_away(&ptr); /* ptr is live but invalid here */ } |
...