zoukankan      html  css  js  c++  java
  • 【Objective-C】09-空指针和野指针

    一、什么是空指针和野指针

    1.空指针

    1> 没有存储不论什么内存地址的指针就称为空指针(NULL指针)

    2> 空指针就是被赋值为0的指针。在没有被详细初始化之前。其值为0。

    以下两个都是空指针:

    1 Student *s1 = NULL;
    2 
    3 Student *s2 = nil;

     

    2.野指针

    "野指针"不是NULL指针,是指向"垃圾"内存(不可用内存)的指针。野指针是很危急的。

     

    二、野指针和空指针样例

    接下来用一个简单的样例对照一下野指针和空指针的差别

    1.首先。打开Xcode的内存管理调试开关,它能帮助检測垃圾内存

      

     

     

    2.自己定义Student类。在main函数中加入下列代码

    复制代码
    1 Student *stu = [[Student alloc] init];
    2 
    3 [stu setAge:10];
    4 
    5 [stu release];
    6 
    7 [stu setAge:10];
    复制代码

    执行程序。你会发现第7行报错了。是个野指针错误!

     

    3.接下来分析一下报错原因

    1> 运行完第1行代码后,内存中有个指针变量stu,指向了Student对象

    Student *stu = [[Student alloc] init];

    如果Student对象的地址为0xff43,指针变量stu的地址为0xee45。stu中存储的是Student对象的地址0xff43。即指针变量stu指向了这个Student对象。

     

    2> 接下来是第3行代码

    [stu setAge:10];

    这行代码的意思是:给stu所指向的Student对象发送一条setAge:消息,即调用这个Student对象的setAge:方法。眼下来说。这个Student对象仍存在于内存中。所以这句代码没有不论什么问题。

     

    3> 接下来是第5行代码

    [stu release];

    这行代码的意思是:给stu指向的Student对象发送一条release消息。在这里。Student对象接收到release消息后,会立即被销毁。所占用的内存会被回收。

    (release的具体使用方法会放到OC内存管理中具体讨论)

    Student对象被销毁了,地址为0xff43的内存就变成了"垃圾内存",然而。指针变量stu仍然指向这一块内存,这时候。stu就称为了野指针

     

    4> 最后运行了第7行代码

    [stu setAge:10];

    这句代码的意思仍然是: 给stu所指向的Student对象发送一条setAge:消息可是在运行完第5行代码后。Student对象已经被销毁了,它所占用的内存已经是垃圾内存,假设你还去訪问这一块内存。那就会报野指针错误。这块内存已经不可用了,也不属于你了,你还去訪问它,肯定是不合法的。

    所以。这行代码报错了。

     

    4.假设修改一下代码,就不会报错

    复制代码
    1 Student *stu = [[Student alloc] init];
    2 
    3 [stu setAge:10];
    4 
    5 [stu release];
    6 
    7 stu = nil;
    8 
    9 [stu setAge:10];
    复制代码

    注意第7行代码,stu变成了空指针,stu就不再指向不论什么内存了

    由于stu是个空指针。没有指向不论什么对象,因此第9行的setAge:消息是发不出去的,不会造成不论什么影响。当然。肯定也不会报错。

     

    5.总结

    1> 利用野指针发消息是非常危急的,会报错。也就是说,假设一个对象已经被回收了,就不要再去操作它,不要再尝试给它发消息。

    2> 利用空指针发消息是没有不论什么问题的,也就是说以下的代码是没有错误的:

    [nil setAge:10];
  • 相关阅读:
    ASP.NET CORE 使用Consul实现服务治理与健康检查(2)——源码篇
    ASP.NET CORE 使用Consul实现服务治理与健康检查(1)——概念篇
    Asp.Net Core 单元测试正确姿势
    如何通过 Docker 部署 Logstash 同步 Mysql 数据库数据到 ElasticSearch
    Asp.Net Core2.2 源码阅读系列——控制台日志源码解析
    使用VS Code 开发.NET CORE 程序指南
    .NetCore下ES查询驱动 PlainElastic .Net 升级官方驱动 Elasticsearch .Net
    重新认识 async/await 语法糖
    EF添加
    EF修改部分字段
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7202493.html
Copyright © 2011-2022 走看看