0xDEADBEEF与NULL [英] 0xDEADBEEF vs. NULL

查看:1481
本文介绍了0xDEADBEEF与NULL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

纵观各种code,我看到人们要么归零内存(memset的(PTR,NULL,大小)或0xDEADBEEF(memset的(PTR,0xDEADBEEF,大小)在调试时分配内存builds.So ..


  1. 什么是优势利用各一个,以及什么是一般preferred方式C / C ++实现这一++?

  2. 此外,如果一个指针被分配0xDEADBEEF的价值可能不是依然尊重有效的数据?


解决方案

  1. 无论是使用 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个字节的内存区域。


  2. 在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..

  1. What is the advantages to using each one, and what is the generally preferred way to achieve this in C/C++?
  2. Also if a pointer was assigned a value of 0xDEADBEEF couldn't it still deference to valid data?

解决方案

  1. Using either memset(ptr, NULL, size) or memset(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++ if NULL 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 of memset is an integer, not a pointer. The proper way to zero-out a memory block would be memset(ptr, 0, size). Note: 0 not NULL. I'd say that even memset(ptr, '\0', size) looks better than memset(ptr, NULL, size).

    Moreover, the most recent (at the moment) C++ standard - C++11 - allows defining NULL as nullptr. nullptr value is not implicitly convertible to type int, 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 type int, which means that in general case memset(ptr, NULL, size) is simply invalid code in C.

    Secondly, even though the second parameter of memset has type int, the function interprets it as an unsigned char value. It means that only one lower byte of the value is used to fill the destination memory block. For this reason memset(ptr, 0xDEADBEEF, size) will compile, but will not fill the target memory region with 0xDEADBEEF values, as the author of the code probably naively hoped. memset(ptr, 0xDEADBEEF, size) is eqivalent to memset(ptr, 0xEF, size) (assuming 8-bit chars). While this is probably good enough to fill some memory region with intentional "garbage", things like memset(ptr, NULL, size) or memset(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, like 0xAB or 0xEF. If this is good enough for your purposes, use memset. If you want a more expressive and unique garbage value, like 0xDEDABEEF or 0xBAADFOOD, you won't be able to use memset with it. You'll have to write a dedicated function that can fill memory region with 4-byte pattern.

  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆