3

Uninitialized variables may have indeterminate values, as this answer to an earlier question points out. Is there a way to specify this indeterminate data to, say, repeat 0xDEADDEAD? The indeterminate data is apparently compiler-specific, but it would always be nice to force it to be something easily recognizable.

Are there existing memory leak/corruption detection libraries allowing this? Overloading new seems like a solution in some cases, but I'd rather not delve into that trickery myself.

The problem is that indeterminate values usually cause undefined behaviour of code, and rarely occurring run time bugs, so, for example, I'd like to spot if I've forgotten a memset() somewhere in my code. Maybe even randomizing the indeterminate values could serve as a test bench.

In case this is not possible, are there better approaches to solve the problem?

Community
  • 1
  • 1
phero
  • 31
  • 3
  • 3
    Have you considered using valgrind? – Ignacio Vazquez-Abrams Jun 02 '12 at 06:11
  • I have quite little experience on memory corruption detection, so I'm looking for any solutions that work. Do you think Valgrind would spot these problems? Thanks in any case, I'll look into it. – phero Jun 02 '12 at 06:24
  • 1
    Well the problem that will always persist is to use pointers to previously valid data, data that is already freed and is now being used by another part of your program: `0xDEADDEAD` and likes are not the answer. Just be careful and use RAII. – demorge Jun 02 '12 at 08:16
  • 1
    It is a built-in feature for compilers like MSVC. You however don't get the pick the value that's used to initialize the stack frame. It is always the same, 0xcc for MSVC, a value carefully chosen to generate breakpoints (it is int 3), protection faults when dereferencing an uninitialized pointer (0xcccccccc is always unmapped) and recognizable values that repeat well for simple values. Picking a value like 0xdeadbeef can't work, not every local variable is 4 bytes. – Hans Passant Jun 02 '12 at 12:19
  • Okay, thanks, I guess this settles my original question. It's still good to know that consecutive 0xcc's really mean something with MSVC debugger. There seems to be little documentation for these "features", if at all. – phero Jun 02 '12 at 13:45

3 Answers3

0

Here are some guidelines for producing good quality C code:

  1. Create/use coding guidelines that help avoid memory bugs (and other types of bugs). There are many examples on the internet. The best approach is to take a look at 5 or 6 and compile it into one, keeping just the things that fit your needs.
  2. Use code reviews/inspections to find bugs and to check adherence to the coding guidelines. Code reviews is one of the best ways to find bugs that are undetectable by tools. Code reviews is extra important for beginner/intermiediate programmers, because it adds to your learning curve, both when you review code that others have written and when you are being reviewed.
  3. Test your code with test cases that can be run automatically.
  4. Use tools like valgrind to find many types of bugs.
Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
0

To check the pattern of the value of the variables at runtime is a little bit tricky. As you say, it is compiler/architecture dependent.

Usually static analysis tools can give you warnings about uninitialized variables. Here's a free static code checker that you can play with: cppcheck.

Alexandru C.
  • 3,337
  • 1
  • 25
  • 27
0

There's indeterminate values, there are memory management errors, and there's the intersection of the two.

I don't know what, if anything C/C++ compilers do for indeterminate values. (A compiler I built for an arguably C like parallel language has an explicit debug switch, that fills every unassigned variable with a value designed to "cause trouble", e.g., for ints, -2^31, for pointers, specific not-void values gauranteed to cause a memory access fault, etc.). I suspect your mileage will vary here by compiler.

Memory management is notoriously hard. In C++ you can use constructors and destructors in a regular way to ensure that many of such errors don't occur, see stackoverflow.com/questions/76796/memory-management-in-c

C is harder, carefully inspecting your code, and ensuring each routine has clear responsibility for either allocation, deallocation or neither will help.

For both C and C++ you can use static analysis tools (Coverity, Fortify) to detect many such allocation errors. Similarly, you can use dynamic analysis tools such as Valgrind, which watches what your object code does and stops it when some memory management errors occur. For C only, you can use our dynamic analysis CheckPointer tool; it will detect all the errors valgrind detects and more (e.g., valgrind can't detect an access outside of a local array [one allocated in your stack]; CheckPointer can).

Ira Baxter
  • 93,541
  • 22
  • 172
  • 341