A point that most of the answers here are not addressing, at least not explicitly, is that a null pointer is a value that exists during execution, and a null pointer constant is a syntactic construct that exists in C source code.
A null pointer constant, as Karlson's answer correctly states, is either an integer constant expression with the value 0 (a simple 0
is the most common example), or such an expression cast to void*
(such as (void*)0
).
NULL
is a macro, defined in <stddef.h>
and several other standard headers, that expands to an implementation-defined null pointer constant. The expansion is typically either 0
or ((void*)0)
(the outer parentheses are needed to satisfy other language rules).
So a literal 0
, when used in a context that requires an expression of pointer type, always evaluates to a null pointer, i.e., a unique pointer value that points to no object. That does not imply anything about the representation of a null pointer. Null pointers are very commonly represented as all-bits-zero, but they can be represented as anything. But even if a null pointer is represented as 0xDEADBEEF
, 0
or (void*)0
is still a null pointer constant.
This answer to the question on stackoverflow covers this well.
This implies, among other things, that memset()
or calloc()
, which can set a region of memory to all-bits-zero, will not necessarily set any pointers in that region to null pointers. They're likely to do so on most implementations, perhaps even all existing ones, but the language doesn't guarantee it.
This question is really a duplicate of this one, but Stack Exchange doesn't allow marking duplicates across sites.
Variables should always have the smallest scope possible. This may lead to the "annoyance" of not being able to access the variables easily, but that is actually the point! The more you hide a variable from intrusion the better. If you can keep a variable safe from all reading and writing except from one point, that is the best! This aids in writing bug-free code.
So to answer your question more specifically, pass variables as follows with #1 being the best method:
- By value
- As a pointer to variables where the address and data are constant
- As a pointer to variables where the address and data are not constant
- Globally to one file only
- Globally to all files
Best Answer
No I wouldn't describe that as a dangling pointer, but it is a memory leak because you do not free the first malloc before the second malloc. A dangling pointer would typically be a pointer which points to something which e.g. has already been freed
Looking at the rest of code sample, f doesn't appear to be used, which is odd, and the cast to (float*) is unnecessary unless you need your code to also compile as C++ (something which was common when C++ was a newish language but not anymore, I suspect this may date your book?). While I can't find the exact book you reference, similar C and C++ books by the authors seem to have fairly poor reviews, you may want to consider a different textbook!