写入外部分配的内存范围时没有错误

时间:2013-01-17 15:11:43

标签: c pointers memory malloc

我的main.c内容:

int main(int argc, char **argv)  
{  
    void * tmp = malloc(8);  
    ((double *)tmp)[0] = 100;  
    ((double *)tmp)[1] = 102;  
    printf("tmp %p\n", tmp);  
    printf("tmp[0] %d %f %p\n", sizeof(((double *)tmp)[0]), ((double *)tmp)[0], &((double *)tmp)[0]);  
    printf("tmp[1] %d %f %p\n", sizeof(((double *)tmp)[1]), ((double *)tmp)[1], &((double *)tmp)[1]);  
    return EXIT_SUCCESS;  
}  

=========================OUTPUT=========================  
tmp 0xee8010  
tmp[0] 8 100.000000 0xee8010  
tmp[1] 8 102.000000 0xee8018  
========================================================

首先,我确实在变量tmp中分配了8个字节的内存,并将数字100分配给地址0xee8010。

((double *)tmp)[0] = 100;  

我还将号码102分配给未分配的内存0xee8018。

((double *)tmp)[1] = 102;  

但是我没有在构建时和运行时看到任何错误消息。为什么不呢?

请帮我理解这一点。 谢谢。

2 个答案:

答案 0 :(得分:3)

写入未分配或写入超出已分配内存的范围会导致 Undefined Behavior(UB) ,这不一定会导致崩溃。
未定义的行为意味着可以观察到任何行为,当发生UB时,编译器实现不需要执行任何特定的操作(就像您期望的那样)。

  

但是我没有在构建时和运行时看到任何错误消息。

对于不遵守语言标准的代码,您会收到编译时错误。在这种情况下,代码遵循语言标准,但做出的结果不是由语言标准定义的。

答案 1 :(得分:0)

一个好习惯是始终将malloc()调用与free()匹配。另一个容易出错的习惯就是施法。如果指针被声明为double,则可以在malloc()中自动获得其大小,并降低意外地将指针强制转换为变量的风险,反之亦然。

c中没有缓冲区溢出的运行时警告,因为它被设计为有效地映射到机器代码。要捕获内存泄漏和缓冲区溢出,可以使用外部工具valgrind http://valgrind.org/来分析代码。当您访问内存以捕获此未定义的行为时,它将插入额外的指令。

    int main(int argc, char **argv)
    {
            double *tmp;
            if( tmp = malloc(2*sizeof(tmp)) ){
                    tmp[0]=100;
                    tmp[1]=102;
                    printf("tmp %p\n", tmp);
                    printf("tmp[0] %d %f %p\n", (int)tmp[0], tmp[0], &tmp[0]);
                    printf("tmp[1] %d %f %p\n", (int)tmp[1], tmp[1], &tmp[1]);
                    free(tmp);

                    //return EXIT_SUCCESS;  
                    return(0);
            }else{
                    //Malloc failed
                    return(-1);
            }
    }