0xDEADBEEF与NULL [英] 0xDEADBEEF vs. NULL
问题描述
纵观各种code,我看到人们要么归零内存(memset的(PTR,NULL,大小)或0xDEADBEEF(memset的(PTR,0xDEADBEEF,大小)在调试时分配内存builds.So ..
- 什么是优势利用各一个,以及什么是一般preferred方式C / C ++实现这一++?
- 此外,如果一个指针被分配0xDEADBEEF的价值可能不是依然尊重有效的数据?
-
无论是使用
memset的(PTR,NULL,大小)
或memset的(PTR,0xDEADBEEF,大小)
是这样的事实清楚地表明,笔者不明白他们在做什么。首先,
memset的(PTR,NULL,大小)
确实会零出在C和C ++内存块,如果NULL
被定义为一个整体零。然而,使用
NULL
重新present在此背景下,零值是不是一个可以接受的做法。NULL
是专门为指针背景介绍的宏。memset的
的第二个参数是一个整数,而不是一个指针。零出一个内存块的正确方法是将memset的(PTR,0,大小)
。注:0
不是NULL
。我会说,即使memset的(PTR,'\\ 0',大小)
看起来比memset的(PTR,NULL,大小)更好
。此外,最近的(目前)C ++标准 - C ++ 11 - 允许定义
NULL
为nullptr
。nullptr
值不隐式转换为键入INT
,这意味着上述code不能保证编译在C ++ 11及更高版本。在C语言(和你的问题被标记C作为井)宏
NULL
可扩展到(无效*)0
。即使在C(无效*)0
不是隐式转换为键入INT
,这意味着在一般情况下,memset的(PTR,NULL,大小)
是在C根本无效code。其次,尽管第二个参数
memset的
已键入INT
,功能间$ P $点它作为unsigned char型
值。这意味着,只有一个值的低字节被用来填充目标存储器块。为此memset的(PTR,0xDEADBEEF,大小)
将编译,但不会与0xDEADBEEF
填充目标存储区域值,为code的作者可能天真地希望。memset的(PTR,0xDEADBEEF,大小)
是eqivalent到memset的(PTR,0xEF,大小)
(假设8位字符)。虽然这可能是不错的,足以填补某些内存区域故意垃圾,像memset的(PTR,NULL,大小)
或memset的(PTR ,0xDEADBEEF,大小)
还是背叛作者的部分主要缺乏职业精神。此外,因为其他答案已经指出,这里的想法是用垃圾的价值,填补了未使用的内存。零当然不是在此情况下是一个好主意,因为它不是garbagy足够。当使用
memset的
你被限制为一个字节的值,比如是0xAB
或0xEF
。如果这是配不上你的目的,使用memset的
。如果你想要一个更前pressive和独特价值的垃圾,如0xDEDABEEF
或0xBAADFOOD
,你不会可以使用memset的
它。你必须写一个专门的功能,可以填补4个字节的内存区域。 -
在C和C指针++不能分配的任意整数值(不是空指针常量等,即零)。这样的分配只能通过强制的积分值到终场前有明确的转换来实现。正式地说,这样的铸造的结果实现定义。所得到的价值肯定可以找出有效的数据。
Throughout various code, I have seen people either zero out memory(memset(ptr,NULL,size) or 0xDEADBEEF(memset(ptr,0xDEADBEEF,size) memory at allocation in debug builds.So..
- What is the advantages to using each one, and what is the generally preferred way to achieve this in C/C++?
- Also 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++ ifNULL
is defined as an integral zero.However, using
NULL
to represent the zero value in this context is not an acceptable practice.NULL
is a macro introduced specifically for pointer contexts. The second parameter ofmemset
is an integer, not a pointer. The proper way to zero-out a memory block would bememset(ptr, 0, size)
. Note:0
notNULL
. 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
NULL
asnullptr
.nullptr
value 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
NULL
can expand to(void *) 0
. Even in C(void *) 0
is 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
memset
has typeint
, the function interprets it as anunsigned char
value. 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 with0xDEADBEEF
values, 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
memset
you are limited to one-byte values, like0xAB
or0xEF
. If this is good enough for your purposes, usememset
. If you want a more expressive and unique garbage value, like0xDEDABEEF
or0xBAADFOOD
, you won't be able to usememset
with 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.
这篇关于0xDEADBEEF与NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!