在malloc()之后写入指针越界,不会导致错误

mar*_*arr 6 c malloc memory-corruption

当我尝试下面的代码时它工作正常.我错过了什么吗?

main()
{
    int *p;
    p=malloc(sizeof(int));
    printf("size of p=%d\n",sizeof(p));
    p[500]=999999;
    printf("p[0]=%d",p[500]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用malloc(0*sizeof(int))或其他任何东西,但它工作得很好.当我根本不使用malloc时,程序只会崩溃.因此,即使我为数组p分配了0个内存,它仍然可以正确地存储值.那么为什么我甚至不打扰malloc呢?

mar*_*cog 15

似乎工作正常,但它根本不是很安全.通过在分配的内存块之外写入数据,您将覆盖一些不应该覆盖的数据.这是段错误和其他内存错误的最大原因之一,什么你用它出现在这套短节目的工作观察是什么使得它如此难以追捕的根本原因.

阅读本文,特别是关于内存损坏的部分,开始了解问题.

Valgrind是分析内存错误的绝佳工具,例如您提供的错误.

@David做了很好的评论.比较运行的结果,你的代码运行下面的代码.注意后者导致ideone.com上的运行时错误(几乎没有任何有用的输出!)(点击链接),而前者在你经历时成功.

main()
{
    int *p;
    p=malloc(sizeof(int));
    printf("size of p=%d\n",sizeof(p));
    p[500]=999999;
    printf("p[0]=%d",p[500]);
    p[500000]=42;
    printf("p[0]=%d",p[500000]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


MK.*_*MK. 13

如果你不分配内存,p中有垃圾,所以写入它可能会失败.一旦你进行了有效的malloc调用,p指向有效的内存位置,你可以写入它.你正在覆盖你不应该写的内存,但没有人会牵着你的手来告诉你.如果你运行你的程序和一个内存调试器,如valgrind,它会告诉你.欢迎来到C.


Pup*_*ppy 9

写下你的记忆结束是Undefined Behavior™,这意味着任何事情都可能发生 - 包括你的程序运作就好像你刚刚做的那样是完全合法的.程序运行的原因就像你完成的那样malloc(501*sizeof(int))完全是特定于实现的,并且确实可以特定于任何事情,包括月亮的阶段.