The risk is not in the code shown, the risk is in the code after maintenance, modification and reuse. Or in "cargo-cult" copying of the anti-pattern. If for example you added a great deal of code between the initialised ptr
declaration and the malloc()
, it may no longer be clear that the pointer is not yet valid.
Dereferencing a null pointer "by accident" will normally be trapped as a run-time error, so likely to be detected during testing and development and reported at the point of error. Dereferencing a pointer that is a valid address but say refers to a block returned to the heap for re-use may have no immediate observable impact, but may later cause unrelated code to fail, possibly after deployment and in unpredictable ways - those bugs are very difficult to track down.
Dereferencing a pointer that simply has not been initialised, will have undefined behaviour, it may appear to work, it may trigger an exception, it may cause the code to appear to fail at an unrelated location in the code - again such bugs are hard to track down unless you were lucky enough for it to fail immediately - if it happened to be NULL or an invalid address triggering an exception for example.
Besides that, there are no advantages to the "unsafe" code:
int *ptr; //what is risk here?
ptr = (int *)malloc(sizeof(int));
over both safer and simpler code thus:
int* ptr = malloc( sizeof(*ptr) ) ;
Note other improvements in this:
- do not cast a void-pointer to the destination type,
- use the
sizeof
the object pointed to (or a multiple thereof) rather than an explicit type.
Remember in modern C, is is no longer necessary to declare all variables at the start of a brace-block ({...}
) - though you will still see that anti-pattern too - so there are few excuses for not initialising a pointer with a useful value on instantiation.