C-悬挂指针和野指针

一、问题描述

      字符指针传址进入函数,在函数内将指针指向的内存释放、指针置空,在函数外指针地址仍不变;此时访问该悬挂指针指向的内存可能会导致程序异常等问题。

二、悬挂指针和野指针

1.悬挂指针

        悬挂指针是一个指针,它指向的内存在之前是有效的,但由于某些操作(如内存释放)后变得不再有效。悬挂指针仍然保留着指向已释放内存的地址。

static char* g_str = NULL;

static void test(char* str)
{
    //str传址拷贝至函数内,在函数里将str置空,只是下文中str为空指针无法访问,未改变g_str的地址
    str = NULL;
} 

int main()
{
    g_str = (char*)malloc(32);
    free(g_str);
    test(g_str);
    printf("str addr is %p", g_str); //地址非空
    if(g_str != NULL) {
        printf("str addr is %s", g_str); //访问已释放内存
    }
}

导致的问题:

1. 数据不一致:如果悬挂指针指向的内存被操作系统回收并重新分配给其他用途,通过悬挂指针访问该内存可能导致数据不一致;

2. 内存泄漏:如果悬挂指针没有被置为 NULL,内存未回收,可能导致内存泄露;

3. 段错误:如果指针指向的内存已释放,再次访问指针,通常会导致程序触发段错误。

2.野指针

       野指针是一个指针,它指向的内存区域是未定义的,或者不是当前程序分配的内存。这可能包括指向已经被释放的内存、未初始化的指针、或者指向程序栈之外的内存。

1. 未初始化的指针

int main() {
    int *p; // 未初始化的指针
    printf("Value at p: %d\n", *p); // 未定义行为,可能导致程序崩溃
    return 0;
}

2. 指向未定义的内存


int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int *p = arr + 5; // 指向数组最后一个元素的下一个位置
    // p 现在是一个野指针,因为它超出了数组的边界
    printf("Value at p: %d\n", *p); 
    return 0;
}

3. 函数返回局部变量的地址

int *function() {
    int local_var = 42;
    return &local_var; // 返回局部变量的地址
}

int main() {
    int *p = function();
    printf("Value at p: %d\n", *p); // 未定义行为,因为 local_var 已经超出作用域
    return 0;
}

        local_var变量在函数执行结束时,内存会被释放,此时返回函数的地址;使得p指向了未定义的内存,可能会程序异常或读取到错误数据。


总结

    函数内需要谨慎进行址传递,可以通过动态申请内存、使用后释放的方式,防止指针指向未定义内存;为指针动态申请内存、释放内存后,需要将指针置空,防止出现悬挂指针访问异常情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值