具体来说,转换 malloc 的结果有什么危险? [英] Specifically, what's dangerous about casting the result of malloc?
问题描述
现在,在人们开始将此标记为重复之前,我已阅读以下所有内容,但没有提供我正在寻找的答案:
Now before people start marking this a dup, I've read all the following, none of which provide the answer I'm looking for:
C FAQ 和上述问题的许多答案都引用了一个神秘的错误,即转换 malloc
的返回值可以隐藏;然而,他们都没有给出实践中这种错误的具体例子.现在注意我说的是错误,而不是警告.
Both the C FAQ and many answers to the above questions cite a mysterious error that casting malloc
's return value can hide; however, none of them give a specific example of such an error in practice. Now pay attention that I said error, not warning.
现在给出以下代码:
#include <string.h>
#include <stdio.h>
// #include <stdlib.h>
int main(int argc, char** argv) {
char * p = /*(char*)*/malloc(10);
strcpy(p, "hello");
printf("%s
", p);
return 0;
}
使用 gcc 4.2 编译上述代码,使用和不使用强制转换都会给出相同的警告,并且程序正确执行并在两种情况下提供相同的结果.
Compiling the above code with gcc 4.2, with and without the cast gives the same warnings, and the program executes properly and provides the same results in both cases.
anon@anon:~/$ gcc -Wextra nostdlib_malloc.c -o nostdlib_malloc
nostdlib_malloc.c: In function ‘main’:
nostdlib_malloc.c:7: warning: incompatible implicit declaration of built-in function ‘malloc’
anon@anon:~/$ ./nostdlib_malloc
hello
那么谁能给出一个具体的代码示例,说明由于转换 malloc
的返回值而可能发生的编译或运行时错误,或者这只是一个都市传说?
So can anyone give a specific code example of a compile or runtime error that could occur because of casting malloc
's return value, or is this just an urban legend?
编辑关于这个问题,我遇到了两个写得很好的论点:
Edit I've come across two well written arguments regarding this issue:
- 支持铸造:CERT 咨询:立即将内存分配函数调用的结果转换为指向分配类型的指针
- 反对强制转换(截至 2012-02-14 的 404 错误:使用 互联网档案Wayback Machine 复制自 2010-01-27.{2016-03-18:由于 robots.txt,页面无法抓取或显示."})
- In Favor of Casting: CERT Advisory: Immediately cast the result of a memory allocation function call into a pointer to the allocated type
- Against Casting (404 error as of 2012-02-14: use the Internet Archive Wayback Machine copy from 2010-01-27.{2016-03-18:"Page cannot be crawled or displayed due to robots.txt."})
推荐答案
您不会收到编译器错误,而是编译器警告.正如您引用的消息来源所说(尤其是第一个),您可以 在不包含 stdlib.h
的情况下使用强制转换时会出现不可预测的运行时错误.
You won't get a compiler error, but a compiler warning. As the sources you cite say (especially the first one), you can get an unpredictable runtime error when using the cast without including stdlib.h
.
所以你这边的错误不是演员,而是忘记包含stdlib.h
.编译器可能假设 malloc
是一个返回 int
的函数,因此将 malloc
实际返回的 void*
指针转换为int
然后由于显式转换而指向您的指针类型.在某些平台上,int
和指针可能占用不同的字节数,因此类型转换可能会导致数据损坏.
So the error on your side is not the cast, but forgetting to include stdlib.h
. Compilers may assume that malloc
is a function returning int
, therefore converting the void*
pointer actually returned by malloc
to int
and then to your pointer type due to the explicit cast. On some platforms, int
and pointers may take up different numbers of bytes, so the type conversions may lead to data corruption.
幸运的是,现代编译器会给出指向您实际错误的警告.请参阅您提供的 gcc
输出:它警告您 implicit 声明 (int malloc(int)
) 与内置 <代码>malloc.所以即使没有 stdlib.h
,gcc
似乎也知道 malloc
.
Fortunately, modern compilers give warnings that point to your actual error. See the gcc
output you supplied: It warns you that the implicit declaration (int malloc(int)
) is incompatible to the built-in malloc
. So gcc
seems to know malloc
even without stdlib.h
.
省略演员表以防止此错误与写作的推理大致相同
Leaving out the cast to prevent this error is mostly the same reasoning as writing
if (0 == my_var)
代替
if (my_var == 0)
因为如果将 =
和 ==
混淆,后者可能会导致严重的错误,而第一个会导致编译错误.我个人更喜欢后一种风格,因为它更能反映我的意图,而且我不会犯这种错误.
since the latter could lead to a serious bug if one would confuse =
and ==
, whereas the first one would lead to a compile error. I personally prefer the latter style since it better reflects my intention and I don't tend to do this mistake.
对于转换由 malloc
返回的值也是如此:我更喜欢在编程中明确,我通常会仔细检查以包含我使用的所有函数的头文件.
The same is true for casting the value returned by malloc
: I prefer being explicit in programming and I generally double-check to include the header files for all functions I use.
这篇关于具体来说,转换 malloc 的结果有什么危险?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!