Throughout various code, I have seen memory allocation in debug builds with NULL…
memset(ptr,NULL,size);
Or with 0xDEADBEEF…
memset(ptr,0xDEADBEEF,size);
- What are the advantages to using each one, and what is the generally preferred way to achieve this in C/C++?
- If a pointer was assigned a value of
0xDEADBEEF, couldn’t it still deference to valid data?
Using either
memset(ptr, NULL, size)ormemset(ptr, 0xDEADBEEF, size)is a clear indication of the fact that the author did not understand what they were doing.Firstly,
memset(ptr, NULL, size)will indeed zero-out a memory block in C and C++ ifNULLis defined as an integral zero.However, using
NULLto represent the zero value in this context is not an acceptable practice.NULLis a macro introduced specifically for pointer contexts. The second parameter ofmemsetis an integer, not a pointer. The proper way to zero-out a memory block would bememset(ptr, 0, size). Note:0notNULL. I’d say that evenmemset(ptr, '\0', size)looks better thanmemset(ptr, NULL, size).Moreover, the most recent (at the moment) C++ standard – C++11 – allows defining
NULLasnullptr.nullptrvalue is not implicitly convertible to typeint, which means that the above code is not guaranteed to compile in C++11 and later.In C language (and your question is tagged C as well) macro
NULLcan expand to(void *) 0. Even in C(void *) 0is not implicitly convertible to typeint, which means that in general casememset(ptr, NULL, size)is simply invalid code in C.Secondly, even though the second parameter of
memsethas typeint, the function interprets it as anunsigned charvalue. It means that only one lower byte of the value is used to fill the destination memory block. For this reasonmemset(ptr, 0xDEADBEEF, size)will compile, but will not fill the target memory region with0xDEADBEEFvalues, as the author of the code probably naively hoped.memset(ptr, 0xDEADBEEF, size)is eqivalent tomemset(ptr, 0xEF, size)(assuming 8-bit chars). While this is probably good enough to fill some memory region with intentional “garbage”, things likememset(ptr, NULL, size)ormemset(ptr, 0xDEADBEEF, size)still betray the major lack of professionalism on the author’s part.Again, as other answer have already noted, the idea here is to fill the unused memory with a “garbage” value. Zero is certainly not a good idea in this case, since it is not “garbagy” enough. When using
memsetyou are limited to one-byte values, like0xABor0xEF. If this is good enough for your purposes, usememset. If you want a more expressive and unique garbage value, like0xDEDABEEFor0xBAADFOOD, you won’t be able to usememsetwith it. You’ll have to write a dedicated function that can fill memory region with 4-byte pattern.A pointer in C and C++ cannot be assigned an arbitrary integer value (other than a Null Pointer Constant, i.e. zero). Such assignment can only be achieved by forcing the integral value into the pointer with an explicit cast. Formally speaking, the result of such a cast is implementation defined. The resultant value can certainly point to valid data.