Example -
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void alloco(int **ppa)
{
int i;
int *p;
printf("inside alloco");
p = malloc(10 * sizeof(int));
memset(p,0x0, 10 * sizeof(int));
p[4] = 9;
p[9] = 9;
p[8] = 123; // fill the 10 chunks of memory
printf("size of a %d \n", sizeof(p));
free(p); //free the pointer!!
for(i = 0; i < 10; i++)
printf("a[%d] = %d \n", i, p[i]); //accessing a freed pointer, shouldn't it crash?!
*ppa = p; // pointing to a freed address.
}
int main()
{
int *app = NULL;
int i;
printf("inside main\n");
alloco(&app);
for(i = 0; i < 10; i++)
printf("app[%d] = %d \n", i, app[i]); //getting the same filled contents!
return 0;
}
在alloco中访问指针 p 的释放指针,输出是否不会产生预期的分段错误?我的理解是否正确?
答案 0 :(得分:6)
您的代码具有未定义的行为,因为您正在访问您不再拥有的内存(因为您已将其释放)。
未定义的行为意味着任何事情都可能发生。任何事情,包括你的程序表现得好像你没有释放,segfaulting,打印随机垃圾。
您无法推断未定义的程序的行为。你不能依赖于它做任何特定的事情,比如触发分段错误。
从C11草案中支持上述声明的一些标准:
§6.2.4对象的存储持续时间
- 对象的生命周期是程序执行的一部分,在此期间保证为其保留存储。存在一个对象,具有一个常量地址,并在其整个生命周期内保留其最后存储的值。 如果某个对象被引用到其外部 生命周期,行为未定义。当指针指向(或刚刚过去)的对象到达其生命周期结束时,指针的值变得不确定。
醇>
§7.22.3内存管理功能
[...]分配对象的生命周期从分配延伸 直到解除分配。 [...]
着名的未定义行为定义:
3.4.3未定义的行为
行为,使用不可移植或错误的程序结构或错误数据,本国际标准不强制要求
注意可能的未定义行为包括完全忽略具有不可预测结果的情况,在转换或程序执行期间以环境特征(有或没有发出诊断消息)的文档化方式执行,以终止翻译或执行(发布诊断信息)。