【问题标题】:How is it possible that my code exceeds the size of i allocated with malloc and not give error [duplicate]我的代码怎么可能超过我用 malloc 分配的大小而不给出错误 [重复]
【发布时间】:2021-01-06 18:10:24
【问题描述】:

我用 malloc 分配了 1 个字节,但我可以在这个数组中放置超过 1 个整数,其中 ptr 指向数组的第一个元素。这怎么可能?

    int main(){
    int *ptr = (int*)malloc(sizeof(int));
    ptr[1] = 5;
    ptr[10] = 12;

    printf("%d %d\n",ptr[1], ptr[10]);
    }

输出:5 12

【问题讨论】:

  • 未定义的行为。
  • 我知道我的问题是为什么不给出任何错误。我分配了 1 个 int 字节所以 4 字节但我可以放置 2. 和 11. 元素并打印。为什么??
  • 因为正如@EOF 所说,行为未定义

标签: c memory dynamic malloc allocation


【解决方案1】:

我用 malloc 分配 1 个字节

您没有分配 1 个字节。你分配了 1 个int

但我可以在这个数组中放入超过 1 个整数

ptr[1] = 5;  
ptr[10] = 12;

这称为未定义的行为。

取消对尚未明确初始化的指针的引用

您可以查看这个答案,其中列出了 C++ 中最常见的未定义行为,其中一些(包括您的情况)也适用于 C。

https://stackoverflow.com/a/367662/4975822

【讨论】:

  • 你从哪里得到“执行指针算术......”的东西?错了。
  • @EOF 是的,它正在取消引用
  • 哦,即使指针算术 可以 是未定义的(ptr[10] 即使没有取消引用也是未定义的),但是允许指向 就在对象之后,因此您的部分答案不正确。
  • is undefined even without the dereferencing - 对吗?如果你只是ptr + 10 即只取地址不是UB,是吗?
  • 否则请指出来源是这样说的
【解决方案2】:

C 是一种低级语言,它信任您以确保您编写的代码是安全的。与其他高级语言不同,在运行时或编译时没有检查。

记住这一点,在这种情况下,您为一个整数(可能是四个字节而不是 1 个字节)分配了内存。Malloc 会返回一个指针,该指针不包含有关块大小的任何信息你已经分配了。

ptr[0] = 5

相当于写

*ptr = 5

请注意,在 C 中,数组的第一个元素是 0 而不是 1。

没有检查ptr 是否指向有效的内存块。

写作时也是如此

ptr[10] = 5

相当于写作

*(ptr+10) = 5

在这种情况下这是未定义的行为,编译器和运行时可以做任何事情,包括产生你想要的结果!

至于它是如何工作的,很可能从中分配整数的堆包含足够的空间,超出分配的空间,您可以写入而不会导致访问冲突。

在实际程序中,空间可能完全未被使用,因此没有明显的不良影响(有时),或者它可能被程序中的其他代码或运行时使用以跟踪堆中的分配。

缺少运行时检查使 C 语言非常强大和高效,但也使得编写不稳定或不安全的代码变得容易。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-13
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多