I am a big believer of using the assert() macro in C code.
assert() helps debug code, and also self documents code by stating preconditions explicity that would otherwise require inline documentation. I suggest that all functions have a series of assertions in the prologue, to state exactly what is required.
Simple assertions for example are in the case of pointers not being NULL. Another tip to follow is assigning NULL to pointers that are no longer in use.
When the code is ready for production, the NDEBUG macro can be defined, which means the assert macro evaluates to nothing. This eliminates any performance penalties. It can be equally useful to leave the asserts functional if performance is not critical.