不要将malloc后的地址赋予两个指针变量!

不要将malloc后的地址赋予两个指针变量!当free释放内存空间后,必须将所有指向该地址的指针置为空(NULL),否者野指针(指向被释放后的空间)会导致不可预料的错误。

特别在大型项目中,若ptr1=ptr2指向同一动态分配的内存,而两个指针在不同的线程不同的函数,容易出现,”free(ptr1);ptr1=NULL;“,释放内存空间后ptr2未置为空,仍指向原空间地址,而free的原意是告知系统不在需要该空间,将其变为待分配空间,可被重新分配,因此该空间数据不可预料,ptr2所在的线程对该空间的访问会导致不可预料的错误(ptr2本就不该被使用了)。

如下为测试分析free函数释放后原内存空间中值的变化。
测试代码:

#include<stdio.h>
#include<stdlib.h>

#define NULL ((void *)0)

int main()
{
    char *ptr1 = (char *) malloc(20);
    char *ptr2 = ptr1;//两个指针指向同一(被分配20字节)内存地址空间
    printf("the pointer value of ptr1 is %p\n", ptr1);
    printf("the pointer value of ptr2 is %p\n", ptr2);

    int n = snprintf(ptr1, 20, "0123456789abcdef");
    printf("n is %d\n", n);
    printf("ptr1 = %s\n", ptr1);
    printf("ptr2 = %s\n", ptr2);

    free(ptr1);//释放ptr1或者说ptr2指向的内存空间
    ptr1 = NULL;//将ptr1置为空,但ptr2未被置为空,ptr2变为野指针
    printf("******free(ptr1)及ptr1 = NULL后:**********\n");
    printf("the pointer value of ptr1 is %p\n", ptr1);
    printf("the pointer value of ptr2 is %p\n", ptr2);
    printf("ptr1 = %s\n", ptr1);
    printf("ptr2 = %s\n", ptr2);

    for(int i = 0; i < 20; i++)
    {
        printf("ptr2[%d] = %c\n", i, ptr2[i]);
    }

    return 0;
}

执行结果:

xiaobai@xiaobai-kylin:~/Documents/test$ gcc -std=gnu99 test.c
xiaobai@xiaobai-kylin:~/Documents/test$ 
xiaobai@xiaobai-kylin:~/Documents/test$ 
xiaobai@xiaobai-kylin:~/Documents/test$ ./a.out 
the pointer value of ptr1 is 0x23f1010
the pointer value of ptr2 is 0x23f1010
n is 16
ptr1 = 0123456789abcdef
ptr2 = 0123456789abcdef
******free(ptr1)及ptr1 = NULL:**********
the pointer value of ptr1 is (nil)
the pointer value of ptr2 is 0x23f1010
ptr1 = (null)
ptr2 = 
ptr2[0] = 
ptr2[1] = 
ptr2[2] = 
ptr2[3] = 
ptr2[4] = 
ptr2[5] = 
ptr2[6] = 
ptr2[7] = 
ptr2[8] = 8
ptr2[9] = 9
ptr2[10] = a
ptr2[11] = b
ptr2[12] = c
ptr2[13] = d
ptr2[14] = e
ptr2[15] = f
ptr2[16] = 
ptr2[17] = 
ptr2[18] = 
ptr2[19] = 
xiaobai@xiaobai-kylin:~/Documents/test$ 

从上面的测试结果可看出,释放ptr2指向的空间后,用野指针ptr2访问改空间的每一个元素,发现,其中有些元素变为结束符‘/0’,有些仍保持原数据。
free函数并非将该空间的值都置为‘0’了。这与系统的实现有关。

使用C++的引用是避免出现野指针的较好的方式。也可以说,C++的引用就是对C指针导致的问题的改进。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值