访问一个释放的指针,不应该输出一个分段错误吗? [英] Accessing a freed pointer, shouldn't output be a segmentation fault?

查看:40
本文介绍了访问一个释放的指针,不应该输出一个分段错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

示例 -#include #include #include void alloco(int **ppa){国际我;国际*p;printf("内部alloco");p = malloc(10 * sizeof(int));memset(p,0x0, 10 * sizeof(int));p[4] = 9;p[9] = 9;p[8] = 123;//填充10块内存printf("%d \n 的大小", sizeof(p));免费(p);//释放指针!!for(i = 0; i <10; i++)printf("a[%d] = %d \n", i, p[i]);//访问一个释放的指针,它不应该崩溃吗?!*ppa = p;//指向一个释放的地址.}int main(){int *app = NULL;国际我;printf("在主目录中\n");alloco(&app);for(i = 0; i <10; i++)printf("app[%d] = %d \n", i, app[i]);//获取相同的填充内容!返回0;}

访问一个释放的指针,它是alloco 内部的指针p,输出不应该产生预期的分段错误吗?我的理解正确吗?

解决方案

您的代码具有未定义行为,因为您正在访问您不再拥有的内存(自从您释放了它).>

未定义的行为意味着任何事情都可能发生.任何东西,包括你的程序表现得好像你没有释放一样,段错误,打印随机垃圾.

您无法对未定义程序的行为进行推理.您不能依赖它执行任何特定操作,例如触发分段错误.


一些标准来支持上述声明,来自 C11 草案:

<块引用>

§6.2.4 对象的存储时间

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

<块引用>

§7.22.3 内存管理函数

[...] 分配对象的生命周期从分配开始直到解除分配.[...]

还有著名的未定义行为定义:

<块引用>

3.4.3 未定义行为

行为,在使用不可移植或错误的程序结构或错误数据时,本国际标准对此没有要求

注意 可能的未定义行为范围从完全忽略具有不可预测结果的情况,在翻译或程序执行期间以环境特征的文件化方式(有或没有发布诊断消息)的行为,到终止一个翻译或执行(发出诊断消息).

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;
}

Accessing a freed pointer that is pointer p inside alloco, shouldn't the output produce a expected segmentation fault? Is my understanding correct?

解决方案

Your code has undefined behavior because you're accessing memory that you do not own anymore (since you freed it).

Undefined behavior means that anything can happen. Anything at all, including your program behaving as if you hadn't freed, segfaulting, printing random garbage.

You cannot reason about the behavior of a program that is undefined. You cannot rely on it doing anything specific like triggering a segmentation fault.


Some standardeese to back up the claims above, from a C11 draft:

§6.2.4 Storage duration of objects

  1. The lifetime of an object is the portion of program execution during which storage is guaranteed to be reserved for it. An object exists, has a constant address, and retains its last-stored value throughout its lifetime. If an object is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.

§7.22.3 Memory management functions

[...] The lifetime of an allocated object extends from the allocation until the deallocation. [...]

And the famous Undefined behavior definition:

3.4.3 undefined behavior

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

这篇关于访问一个释放的指针,不应该输出一个分段错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆