访问一个释放的指针,不应输出分段错误?

时间:2015-05-02 07:53:39

标签: c pointers

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 的释放指针,输出是否不会产生预期的分段错误?我的理解是否正确?

1 个答案:

答案 0 :(得分:6)

您的代码具有未定义的行为,因为您正在访问您不再拥有的内存(因为您已将其释放)。

未定义的行为意味着任何事情都可能发生。任何事情,包括你的程序表现得好像你没有释放,segfaulting,打印随机垃圾。

您无法推断未定义的程序的行为。你不能依赖于它做任何特定的事情,比如触发分段错误。

从C11草案中支持上述声明的一些标准:

  

§6.2.4对象的存储持续时间

     
      
  1. 对象的生命周期是程序执行的一部分,在此期间保证为其保留存储。存在一个对象,具有一个常量地址,并在其整个生命周期内保留其最后存储的值。 如果某个对象被引用到其外部   生命周期,行为未定义。当指针指向(或刚刚过去)的对象到达其生命周期结束时,指针的值变得不确定。
  2.   
  

§7.22.3内存管理功能

     

[...]分配对象的生命周期从分配延伸   直到解除分配。 [...]

着名的未定义行为定义:

  

3.4.3未定义的行为

     

行为,使用不可移植或错误的程序结构或错误数据,本国际标准不强制要求

     

注意可能的未定义行为包括完全忽略具有不可预测结果的情况,在转换或程序执行期间以环境特征(有或没有发出诊断消息)的文档化方式执行,以终止翻译或执行(发布诊断信息)。