c - 具体来说,转换 malloc 的结果有什么危险?

标签 c

现在,在人们开始将此标记为重复之前,我已经阅读了以下所有内容,但没有一个提供我正在寻找的答案:

  1. C FAQ: What's wrong with casting malloc's return value?
  2. SO: Should I explicitly cast malloc()’s return value?
  3. SO: Needless pointer-casts in C
  4. 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 的返回值而可能发生的编译或运行时错误,或者这只是一个都市传说?

编辑 关于这个问题,我遇到了两个写得很好的论点:

  1. 支持类型转换:CERT 咨询:Immediately cast the result of a memory allocation function call into a pointer to the allocated type
  2. 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.hgcc 似乎也知道 malloc

省略强制转换以防止出现此错误与编写的推理基本相同

if (0 == my_var)

代替

if (my_var == 0)

因为如果混淆 === 后者可能会导致严重的错误,而第一个会导致编译错误。我个人更喜欢后一种风格,因为它更能反射(reflect)我的意图,而且我不会犯这种错误。

转换 malloc 返回的值也是如此:我更喜欢在编程中明确,并且我通常会仔细检查以包含我使用的所有函数的头文件。

关于c - 具体来说,转换 malloc 的结果有什么危险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1565496/

相关文章:

c - FFTW:3D 数据的 2D 傅里叶变换输出数组的大小

关于 getchar()/putchar() 功能的说明

c - 如何指定 zlib 膨胀大小

c - 总和未正确存储

用C中的数组将行更改为列

c - 将文件中的字符串存储到动态分配的数组中

c - 生产者-消费者堆栈行为而不是队列

从 Fortran 调用 C dll

c - 在表达式中执行增量的问题

C99,C代码中的变量放置