由于担心我发现我的大部分代码确实违反了 c99 规则,导致未定义行为的原因,我开始明确阅读 ISO/IEC 9899:TC3 草案文件。尤其是附录“J.2 未定义的行为”,其中大部分对我来说是合乎逻辑的,为什么很难编译违反这些规则的代码,或者在某些情况下,我至少可以认为“好吧,我不明白,有什么问题,但我'会'那样做”但有一点......
“调用请求大小为零的 calloc、malloc 或 realloc 函数返回的非空指针用于访问对象 (7.20.3)。”
(对于所有尚未阅读 ISO/IEC 9899:TC3“J.2 未定义行为”的人,本节仅解释哪些情况会遇到未定义行为)。
所以我脑子里有很多关于那个案子的问题。
首先:
为什么我要分配一个大小为零的内存块?
当我有这样的块时,我能用它做什么?
为了避免未定义的行为,我可能不想访问它指向的内存......
所以我做了更多的研究......寻找一些不同的 malloc() 手册页。并在 Linux malloc(3) 手册中找到:
“如果 size 为 0,则 malloc() 返回 NULL,或稍后可以成功传递给 free() 的唯一指针值。”
好吧,这对我有帮助的唯一一件事是:我现在向您和我自己提出了其他问题。在相同条件下使用相同参数调用函数可能会返回不同结果的情况并不难想象,好吧……但那些不同的结果大多不必如此不同。这就是让我建议的,指向所请求的零大小块的非空指针可能只是一个不需要的副作用。意思是不是
if ((void *ptr = malloc (0)) == NULL)
{
/*...*/
}
这还不够吗?我必须像这样处理 *alloc 调用吗?
if (X <= 0)
{
if ((*ptr = malloc (X)) != NULL)
{
exit (*);
}
else
{
/*...*/
}
}
else
{
if ((*ptr = malloc (X)) == NULL)
{
/*...*/
}
}
但即使它的预期,得到这样一个
“以后可以成功传递给 free() 的唯一指针值”
,如何使用它?我可以改变它...我什至可以释放它(顺便说一句,这是否意味着我必须释放它,就像我应该对所有其他分配的内存做的那样,或者它只是一个>你被允许,不要破坏你的代码流
像这样制作任何指针有什么区别?
void *X = (void *)"1234abc";
我希望任何人都可以帮助我了解这种科学哲学,或者甚至像我一样对它感兴趣。