linux c 指针和内存分配内存,linux-C基础系列-内存管理(野指针).md

野指针概述

野指针通常指的是指针变量中保存的值不会死一个合法的内存地址,但又对其访问。需要注意的是野指针不是空指针,而是指向内存不可用的指针。

C语言中对于空指针(NULL)是可以判断出来的,但是野指针是无法判断一个非空指针是否为野指针。

野指针一般的来源如下:

局部指针变量没有初始化

#include

int main()

{

char *p;

strcpy(p,"haha"); // 野指针

return 0;

}

使用已释放的指针

int main()

{

int *p = (int *)malloc(sizeof(int)*5);

free(p);

*p = 1; // 野指针

return 0;

}

指针所指向的内存空间在使用前被销毁

#include

char *fun()

{

char p[] = "haha";

return p;

}

int main()

{

char *p = fun();

printf("%s\n",p); // 野指针

return 0;

}

指针经典错误

①被指向的变量没有初始化

②没有为指针指向的内存分配足够的内存

struct Demo

{

int *p;

}

int main()

{

struct Demo d1,d2;

int i;

for(i = 0; i < 10; i++){

d1.p[i] = i; // 未初始化

}

d2.p = (int *)calloc(5,sizeof(int));

for(i = 0; i < 10; i++){

d2.p[i] = i; // 越界,没有分配足够的空间

}

free(d2.p);

return 0;

}

内存分配成功但没有初始化

#include

#include

int main()

{

char *s = (char *)malloc(10);

printf("%s\n",s); // 字符串以 '\0' 为结束符,如不初始化,则未知 '\0'在哪。

free(s);

return 0;

}

数组越界

#include

void fun(int a[10])

{

int i;

for(i = 0; i < 10 ;i++){

a[i] = i; // 越界

printf("%d\n",a[i]);

}

}

int main()

{

int a[5];

fun(a);

return 0;

}

内存泄漏

void fun(unsigned int size)

{

int *p = malloc(sizeof(int) * size);

int i;

if(size % 2 != 0){

return ; // 未释放已申请的内存

}

for(i = 0; i < size ;i++){

p[i] = i;

printf("%d\n",p[i]);

}

free(p);

}

此处可表明,函数设计时最好是单入口单出口。

多次对指针进行内存释放

void fun(int *p,int size)

{

int i;

for(i = 0; i< size; i++){

p[i] = i;

printf("%d\n",p[i]);

}

free(p);

}

int main()

{

int *p = (int *)malloc(5 * sizeof(int));

fun(p,5);

free(p); // 多次释放

return 0;

}

此处可以表明在进行内存操作时,其原则是“谁申请,谁释放”,并且在释放后对指针置空。

使用已释放的指针

void fun(int *p,int size)

{

int i;

for(i = 0; i < size ;i++){

printf("%d\n",p[i]);

}

free(p);

}

int main()

{

int *p = malloc(5 * sizeof(int));

int i = 0;

fun(p,5);

for(i = 0;i < 5 ; i++){

p[i] = i; // 内存空间已释放

}

return 0;

}

内存使用一般规则

① 使用malloc等申请内存后,必须立即检查返回值是否为NULL;

② 牢记数组长度,防止越界操作,可考虑使用柔性数组;

③ 内存申请和释放操作必须匹配,防止内存泄漏也可防止多次释放;

④ 如必须在某个函数中释放一个内存,则建议添加一个参数选项,来显式提醒调用者是否释放内存;

⑤ free后立即将其赋值为NULL,因为free的参数为空时是合法参数;

email: MingruiZhou@outlook.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值