现在,在人们开始将此标记为重复之前,我已经阅读了以下所有内容,但没有一个提供我正在寻找的答案:
- C FAQ: What's wrong with casting malloc's return value?
- SO: Should I explicitly cast malloc()’s return value?
- SO: Needless pointer-casts in C
- SO: Do I cast the result of malloc?
C FAQ 和上述问题的许多答案都引用了一个神秘的错误,转换 malloc
的返回值可以隐藏;但是,它们都没有给出实际中这种错误的具体示例。现在请注意,我说的是错误,而不是警告。
现在给出以下代码:
#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\n", p);
return 0;
}
使用 gcc 4.2 编译上述代码,使用和不使用转换都会给出相同的警告,并且程序正确执行并在两种情况下提供相同的结果。
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
的返回值而可能发生的编译或运行时错误,或者这只是一个都市传说?
编辑 关于这个问题,我遇到了两个写得很好的论点:
- 支持类型转换:CERT 咨询:Immediately cast the result of a memory allocation function call into a pointer to the allocated type
- Against Casting (截至 2012 年 2 月 14 日的 404 错误:使用 2010 年 1 月 27 日的 Internet Archive Wayback Machine 副本。{2016 年 3 月 18 日:“由于 robots.txt,无法抓取或显示页面。”})
最佳答案
您不会收到编译器错误,而是编译器警告。正如您引用的消息来源所说(尤其是 first one ),您可以在使用不包含 stdlib.h 的强制转换时出现不可预测的运行时错误
。
所以你这边的错误不是强制转换,而是忘记包含stdlib.h
。编译器可能会假定 malloc
是一个返回 int
的函数,因此将 malloc
实际返回的 void*
指针转换为int
然后由于显式强制转换为您的指针类型。在某些平台上,int
和指针可能占用不同的字节数,因此类型转换可能会导致数据损坏。
幸运的是,现代编译器会给出指向实际错误的警告。查看您提供的 gcc
输出:它警告您 隐式 声明 (int malloc(int)
) 与内置 malloc
。所以即使没有 stdlib.h
,gcc
似乎也知道 malloc
。
省略强制转换以防止出现此错误与编写的推理基本相同
if (0 == my_var)
代替
if (my_var == 0)
因为如果混淆 =
和 ==
后者可能会导致严重的错误,而第一个会导致编译错误。我个人更喜欢后一种风格,因为它更能反射(reflect)我的意图,而且我不会犯这种错误。
转换 malloc
返回的值也是如此:我更喜欢在编程中明确,并且我通常会仔细检查以包含我使用的所有函数的头文件。
关于c - 具体来说,转换 malloc 的结果有什么危险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1565496/