野指针形成原因和危害以及如何避免

**

1.函数指针 指针函数 指针数组 数组指针

**

int a[][3]={{20,19,18},{33,34,35},{66,37,18},{1,2,3}};
&a代表 指向二维数组的指针
a 代表 二维数组名,指向一维数组a[0],即第1行首地址
a[0] , *(a+0) , *a 都代表 第1行第1列元素地址
a+1 , &a[1] 代表 第二行的首地址
a[1] , *(a+1) 代表 第二行第一列的元素地址(行指针变成了列指针)
a[1]+2 , *(a+1)+2 , &a[1][2] 代表 第二行 第三列的元素地址
*(a[1]+2) , ((a+1)+2) , a[1][2] 代表 第二行 第三列的内容(元素的值)
想取元素内容 要有两个方括号 或者一个方括号一个※号 或者两个※号
指向数组的指针才是行指针 ++ 是移动一行
而指针 是列指针 ++是移动一列 即移动一个元素
【】有两个作用 一个是将数组元素 偏移方括号个位置
第二个是取这个位置的元素内容

指向函数的指针 int (*p)(int x,int y);
将函数名max赋给指针p
p = max;
调用函数有三种方法
1.max(a,b)
2,p(a,b)
3.(*p)(a,b)这个在数组里面不能用 因为数组里面就是取内容了

指针函数 返回的是个指针
局部变量地址不能返回在这里插入图片描述

2.sizeof与strlen的区别

sizeof 计算字符串长度时候会把最后的 ‘\0’ 算进去,而strlen 不会。
所以一般结果就是 sizeof 计算出来的长度 比 strlen的长度要多1个字节。
例如:这个sizeof(“hello”)=6,而strlen(“hello”)=5。
但是sizeof 在计算数组的时候,是计算这个数组的最大长度,而不是数组内部数据的长度。
除此之外,还要注意,当sizeof后面带一个指针的时候,实际上是计算指针的长度,一般32位设备
指针长度是4个字节。而strlen依然是计算指针指向的长度。
例如:
char *a=“hello”;
sizeof(a)=4 <=-====因为a是指针,结果是指针的大小
strlen(a)=5 <======依然是5

3.什么是野指针?应该如何避免?

1).野指针:指向不确定地址的指针变量。(即没有初始化)使用野指针易因内存泄露出现段错误。而造成内存泄露的原因有两个:
(1).访问了没有权限的内存(平时我们正确使用指针的时候,系统应经将相应的内存分配给用户,但是如果指向没有分配的内存,系统会判定我们没有权限)
(2).访问了已经释放了的内存。
2).如何减少这样的现象产生:当一个指针没有指向时,咱们一般默认指向NULL(NULL是代表内存为0的地址,而且NULL是不允许任何操作的);
(1).使用malloc分配内存(申请一个内存)
#difine MAX_SIZE 1024;
char ptr = (char ) maollc (sizeof (char) * MAX_SIZE);
认真研究这样的表达式的优点,这个表达式在代码的维护性,扩展性都大大提高了。这方面是我们平时写代码时所应该提高的。

4.c语言分配内存的方式有哪些?

(1)、静态存储区分配
内存分配在程序编译之前完成,且在程序的整个运行期间都存在,例如全局变量、静态变量等。
(2)、栈上分配
在函数执行时,函数内的局部变量的存储单元在栈上创建,函数执行结束时这些存储单元自动释放。
(3)、堆上分配
堆分配(又称动态内存分配)。程序在运行时用malloc或者new申请内存,程序员自己用free或者delete释放,动态内存的生存期由我们自己决定。

5. c语言中常见的内存错误有哪些?

(1).指针没有指向一块合法的内存
a:结构体成员指针未初始化
b:没有为结构体指针分配足够的内存
c:函数的入口校验
(2)为指针分配的内存太小
a:为指针分配了内存,但是大小不够,导致出现越界错误。
(3)内存分配成功,但并未初始化
定义一个变量时,第一件事就是初始化,在定义变量和数组时也可以初始化
(4)内存越界
内存分配成功,且已经初始化,但是操作越过了内存的边界。这种错误经常是与由于操作数组或指针时出现“多1”或“少1”的情况
(5)内存泄漏
a:使用malloc函数 如:char *p = (char *)malloc(sizeof(指向的数据类型)*100);

b:使用malloc函数要检查内存是否申请成功,if(NULL != p)语句来验证;

c:用malloc函数申请0字节指针时 if(NULL != p)语句校验将不起作用

d:内存释放;使用malloc函数需要用free函数释放该内存块的首地址、使用malloc函数和free函数要对影响等否则发生段错误!

e:内存释放之后:使用函数free之后指针变量本身保存的地址并没有改变,需要重新把p的值变为NULL
5.static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
(1).全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alex、WY

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值