野指针(内存操作的问题及规范

函数指针- 指针变量中的值非法的内存地址,进而形成野指针
- 野指针不是NULL指针,是指向不可用内存地址的指针
- C语言无法判断一个指针所保存的地址是否合法

野指针的由来

  1. 局部指针变量==没有初始化==
  2. 指针所指向的变量==在指针之前被销毁==
  3. 使用已经释放过的指针
  4. 进行了错误的指针运算
  5. 进行了==错误的强制类型转换==

代码示例:

#include <stdio.h>
#include <malloc.h>


int main()
{
    int* p1 = (int*)malloc(40);//申请了40个字节
    int* p2 = (int*)1234567;  //error p2是一个野指针了
    int i = 0;

    for(i=0; i<40; i++)
    {
        *(p1 + i) = 40 - i;//error 由于指针运算产生了野指针,改写了非法的内存地址, p1只有40个字节
    }

    free(p1); //free后,p1里的值还是原来的地址

    for(i=0; i<40; i++)
    {
        p1[i] = p2[i];//error 使用了释放了的指针
    }

    return 0;
}

==free(p);
p = NULL;==
释放后应该养成将指针赋值为NULL的习惯

杜绝野指针的基本原则

  1. 绝不返回==局部==变量和==局部==数组的==地址==
  2. 任何变量定义后必须0初始化(free后给指针赋NULL)
  3. 字符数组必须确认0结束符后才能成为字符串
  4. 任何与内存操作相关的函数必须指定长度信息

    • 错误代码示例:
#include <stdio.h>
#include <string.h>
#include <malloc.h>

struct Student
{
    char* name;
    int number;
};

char* func()
{
    char p[] = "D.T.Software";

    return p; 
}

void del(char* p)
{
    printf("%s\n", p);

    free(p);
}

int main()
{
    struct Student s;//由于没有初始化,产生了野指针
    char* p = func();//产生了野指针

    strcpy(s.name, p); //使用野指针

    s.number = 99;

    p = (char*)malloc(5);

    strcpy(p, "D.T.Software");//产生内存越界,操作了野指针所指向的内存空间

    del(p);

    return 0;
}

常见的内存错误
  1. 结构体成员指针未初始化
  2. 结构体成员指针为分配足够的内存
  3. 内存分配成功,但是未初始化
  4. 内存操作越界
内存操作的规范
  • 动态内存申请后,应该检查是否申请成功,检查指针值是否为NULL
  • free指针之后必须赋值为NULL
int* p = (int *)malloc(5);
if(p != NULL)
{

    //do something

}
free(p);
p = NULL;
  • 任何与内存操作相关的函数必须带长度信息
void print(int* p, int size)
{
    int i = 0;
    char buf[128] = {0};
    snprintf(buf,sizeof(buf),"%s","adgadgdg");
    for(i = 0; i < size;i++)
    {
        printf("%d \n",p[i]);
    }
}
  • malloc操作和free操作必须匹配,防止内存泄漏和多次释放
malloc次数多于free,产生内存泄漏
当malloc次数少于free,程序可能崩溃

所以mallocfree应该成对出现在同一函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值