我的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;
但是我没有在构建时和运行时看到任何错误消息。为什么不呢?
请帮我理解这一点。 谢谢。
答案 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);
}
}