Our CheckPointer tool can detect this using dynamic analysis, along with a wide variety of other memory access errors. The tool tracks all allocations, accesses and assignments involving explicit or implicit pointers, and complains at the earliest moment when such an access is illegal or undefined.
Saving OP's example code as "buggy.c", and running CheckPointer produces the following output (some lines removed for pedagogical reasons):
C~GCC4 CheckPointer Version 1.2.1001
Copyright (C) 2011-2016 Semantic Designs, Inc; All Rights Reserved; SD Confidential Powered by DMS (R) Software Reengineering Toolkit
Parsing source file "E:/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Source/buggy.c" using encoding CP-1252 +CRLF $^J $^M $^e -1 +8 ...
Grouping top level declarations ...
Creating object meta data initializers ...
Normalizing syntax tree ...
Instrumenting syntax tree ...
Ungrouping top level declarations ...
Writing target file "E:/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Target/buggy.c" using encoding CP-1252 +CRLF $^J $^M $^e -1 +8 ...
*** Compiling sources with memory access checking code gcc.exe -I"e:\DMS\Domains\C\GCC4\Tools\CheckPointer" -I.\Target -obuggy.exe Target\buggy.c Target\check-pointer-data-initializers.c "e:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-pointer.c" "e:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-pointer-splay-tree.c" "e:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-pointer-wrappers.c"
*** Executing instrumented application
*** Error: CWE-465 Pointer Issue (subcategory CWE-476, CWE-587, CWE-824, or CWE-825)
Dereference of dangling pointer.
in function: main, line: 8, file E:/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Source/buggy.c
The specific type of error is reported using codes defined by the Common Weakness Enumeration standard.
NIST offers a "torture" test for Java and C errors called Juliet.
Of the 14,195 Juliet test cases that are relevant to the C language, CheckPointer detected 13257 expected memory-access errors. 908 test cases were not diagnosed, but these include ones that contain undefined behavior not related to pointer usage errors (which CheckPointer is not intended to detect), or pointer usage errors that were not exposed by the actual execution (e.g. uninitialized variable contained 0 in actual execution). [We modified some of these examples to ensure that the actual execution did not contain 0 for such variables, and afterwards CheckPointer gave an error message as expected.]
CheckPointer works with GCC and MSVisualStudio.
=======================================
@n.m. made a number of comments to various answers in this thread. He issued a kind of challenge problem where he demonstrated that valgrind can't find a bug in the following code, similar to OPs but more deeply nested:
#include <stdio.h>
void badidea(int**);
void worseidea(int**);
int main(void) {
int* p;
badidea(&p);
// printf("%d\n", *p); /* undefined behavior happens here: p points to x from badidea, which is now out of scope */
worseidea(&p);
return 0;
}
void worseidea(int **p) {
int x = 42;
printf("%d %d\n", **p, x); /* undefined behavior happens here: p points to x from badidea, which is now out of scope */
}
void badidea(int** p) {
int x = 5;
*p = &x;
}
Here's the Checkpointer run, which does diagnose the pointer problem in n.m's code:
C~GCC4 CheckPointer Version 1.2.1001
Copyright (C) 2011-2016 Semantic Designs, Inc; All Rights Reserved; SD Confidential
...
Parsing source file "C:/Users/idbaxter/AppData/Local/Temp/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Source/buggy.c" using encoding CP-1252 +CRLF $^J $^M $^e -1 +8 ...
...
Writing target file "C:/Users/idbaxter/AppData/Local/Temp/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Target/buggy.c" using encoding CP-1252 +CRLF $^J $^M $^e -1 +8 ...
*** Compiling sources with memory access checking code
gcc.exe -I"c:\DMS\Domains\C\GCC4\Tools\CheckPointer" -I.\Target -obuggy.exe Target\buggy.c Target\check-pointer-data-initializers.c "c:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-
pointer.c" "c:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-pointer-splay-tree.c" "c:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-pointer-wrappers.c"
*** Executing instrumented application
*** Error: CWE-465 Pointer Issue (subcategory CWE-476, CWE-587, CWE-824, or CWE-825)
Dereference of dangling pointer.
in function: worseidea, line: 16, file C:/Users/idbaxter/AppData/Local/Temp/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Source/buggy.c
called in function: main, line: 10, file: C:/Users/idbaxter/AppData/Local/Temp/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Source/buggy.c