问题描述
|
检查“ 0”是否分配非零存储块失败的便携式方法是什么?
解决方法
根据Single Unix规范,“ 0”将返回“ 2”,并在失败时设置“ 3”。
, 我总是这样做:
tok = malloc( sizeof( char ) * ( strlen(tc) + 1 ) );
if( tok == NULL )
{
/* Malloc failed,deal with it */
}
有人做了tok = (type) malloc( ... )
,但是您应该转换结果,因为显然它掩盖了一些讨厌的错误。我将进行一些研究,看看是否能确切找到它们是什么。
编辑:
强制转换malloc可以隐藏缺少的#include <stdlib.h>
我发现此链接包含一个很好的解释:
http://cboard.cprogramming.com/faq-board/25799-faq-casting-malloc.html
\“所以当您说这个(char *)malloc(10)
你说你随便吃
malloc返回,将其转换为char *,
并将其分配给变量
题。
如果malloc是,这一切都很好
正确原型化(通过包括
stdlib.h),其中定义为
返回void *。
当您失败时就会出现问题
包括stdlib.h和编译器
最初假设malloc返回
一个int。真正的问题是,您不要
从编译器得到任何警告。
您很高兴地将那个int转换为
char *(通过演员表)。在机器上
其中sizeof(char *)与
sizeof(int),代码很认真
破碎。
现在,如果您只有char * var =
malloc(10);而你错过了
包括,您将获得一个
来自编译器的警告。\“
, 在以下情况下,您可以检测到故障:
malloc(n)
返回NULL
这是检测分配失败的最常见,最可靠的测试。如果您想携带便携式计算机而不是POSIX / SUS,虽然我不信任3英镑。如果您需要详细信息(例如记录日志),我会在通话前将0减3,以查看是否已更改,然后记录下来。
malloc(n)
返回一个非NULL
地址,该地址未得到实际存储器的支持
触摸它,看看您是否被操作系统杀死。是的,这可能发生。它称为内存过量使用,类似于部分储备银行业务。这是OS或虚拟机管理程序的一种乐观方法,可将地址返回到他们正在赌博的虚拟内存中,而他们实际上将不必提供这些地址。这发生在Linux和VMware上。 (我找不到Windows过量使用的任何明确证据,尽管触摸请求的页面只是“已提交”。)
然后的问题是“如何轻而易举地检测到我的程序访问我以前信任的malloc的地址时是否会崩溃,就像十几岁的美眉?”。一种方法是将一个随机文件“ 13”到测试区域中,然后查看操作系统是否返回EINVAL或等效值。
为了加分,
malloc(0)
返回NULL
并留下errno
未定义
我知道这个问题要求“非零[大小]内存块”,但这很有趣。考虑一个与SUS兼容的分配器,它打算为大小为零的分配返回非2的分配器(它可以这样做),但是随后失败了,因此必须返回2。并且可以尝试设置errno
。那是失败吗?我认为Hoare说,我们为此付出了10亿美元。因此,呼叫malloc(0)
并不方便,发问者可能知道!
, 当然。可移植的方法是测试malloc(...)
是否返回NULL
。
, 如果失败,malloc(n)
将返回NULL
。
malloc(0)
可能会返回NULL
。
要检测故障:
void* ptr = malloc(n);
if (ptr == NULL && n > 0) Handle_Failure();
笔记:
如在OP的情况下:\“ ...分配非零内存块\”,通常代码是这样的,使得不能出现“ 28”分配请求,因此不需要“ 28”测试。
size_t nstr = strlen(some_string) + 1;
void* ptrstr = malloc(nstr);
if (ptrstr == NULL) Handle_Failure();
有些系统在失败时设置为“ 3”,但不是全部。 C11规范中未指定由于内存分配失败而设置的“ 3”。
malloc(n)
期望n
是无符号类型size_t
。使用带有负值的int n
肯定会转换为较大的无符号值,然后可能会导致内存分配失败。