-4

我的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;  

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

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

4

2 回答 2

3

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

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

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

于 2013-01-17T15:13:27.057 回答
0

一个好习惯是始终将 malloc() 调用与 free() 匹配。另一个容易出错的习惯是选角。如果指针被声明为双精度,您可以在 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);
            }
    }
于 2014-03-07T08:31:57.887 回答