【问题标题】:Type casting a void pointer to an int with insufficient memory allocation [duplicate]将 void 指针类型转换为内存分配不足的 int [重复]
【发布时间】:2017-10-07 03:36:36
【问题描述】:

我正在用 1 字节的内存初始化一个 void 指针,并将它类型转换为一个 int 指针并取消引用它,给它一个值 3(需要 4 个字节),但它运行良好。这不应该导致错误或导致像OOM这样的运行时异常吗?

void* record = malloc(1);
int i=3;
*((int*)record) = 3;

【问题讨论】:

  • 当你像这样误用指针时,这是未定义的行为。它可以做任何事情:工作与否、崩溃与否、编译器警告与否等等。
  • “理想情况下这不应该导致异常吗?”那将是定义的行为。为什么要定义一种语言必须如何失败?
  • 这里令人讨厌的事实是,无论是否未定义,它实际上都适用于大多数 C++ 实现,因为几乎所有堆实际上都以机器字或机器字的一些小倍数为单位进行分配。也就是说,您会发现您的堆实际上为您的 malloc(1) 调用分配了 4 或 8 或 12 甚至 16 个字节。 (例外情况是那些非常罕见的堆,它们将堆元数据与分配的内存分开,或者对少于一个机器字的分配有特殊处理。)它令人讨厌的原因是它几乎总是可以工作的。直到有一天,它没有。
  • P.S.我说的是 C++ 实现,但也是 C。

标签: c pointers void-pointers


【解决方案1】:

当您写到由malloc 分配的内存块的末尾时,就像您在此处所做的那样,您调用undefined behavior

未定义的行为意味着程序的行为无法预测。它可能会崩溃,它可能会输出奇怪的结果,或者它可能看起来工作正常。此外,看似无关的更改(例如添加未使用的局部变量或调用 printf 进行调试)可能会改变未定义行为的表现方式。

总而言之,对于未定义的行为,仅仅因为程序可能崩溃并不意味着它

【讨论】:

    猜你喜欢
    • 2014-02-06
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 2021-09-20
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多