• 无用单元和悬挂引用


    1.无用单元:

    指一块存储区(或资源),该存储区虽然是程序(或进程)的一部分,但是在程序中却不可再对其引用。

    按照C++的规定,我们可以说,无用单元是程序中没有指针指向的某些资源;

    例如:

    1 void main()
    2 {
    3     char *p = new char[1000];//分配一个包含1000个字符的动态数组
    4     char *q = new char[1000];//另一个动态内存
    5     p = q;//将p和q进行一些操作的代码
    6     /*p所指向的1000个字符的存储区会发生什么?此时,p和q指向相同的区域,没有指针指向之前p指向
    7     的旧存储区!该存储区还在,仍然占用着空间。但是程序已经不能访问该区域*/
    8 }

    2.悬挂引用:

    当两个指针同时指向一个地址时,通过一个指针删除了该地址的数据,另一个指针就产生了悬挂引用。

    1 void main()
    2 {
    3     char *p;
    4     char *q;
    5     p = new char[1024];
    6     q = p;
    7     delete[]p;
    8     p = 0;//现在q就是一个悬挂引用
    9 }

    无用单元控制再软件设计中时一个非常重要的问题,因为它会影响应用的整体性能。

    即使是不太重要的应用程序,再持续运行一段时间未停止,内存泄露也会导致严重的问题。

    随着越来越多的内存变成无用单元,应用程序(和整个系统)的性能逐渐降低,导致越来越多的虚拟内存分页活动。最终,由于分页文件被占满,

    整个系统只能停止。

    并非所有程序都可以随意暂停,如核电站控制程序,一旦暂停可能将导致灾难性的后果。

    C++在何时产生无用单元:

    1.从函数退出时,在函数内部创建的所有局部变量(包括对象)以及按值传递的所有参数都不可访问。

    2.从块退出时,在块内部声明的所有局部变量(包括对象)都不可访问

    3.任何复杂表达式包含的临时变量,在不需要时必须全部予以销毁,否则它们将成为无用单元。

    4.任何动态分配的对象,在不需要时必须由程序员显式地销毁。

     1 TPerson::TPerson(const char _birthData[])
     2     :birthData(_birthData),address(0)
     3 {}
     4 
     5 char *strdup(const char* src)   //辅助函数
     6 {
     7     char *ptr = new char[strlen(src) + 1];
     8     strcpy(ptr, src);
     9     return ptr;
    10 }
    11 
    12 TPerson::TPerson(const char _theName[], const char _theAddress[], unsigned long _theSSN, const char _theBirthDate[])
    13     :ssn(theSSN), birthDate(_theBirthDate)
    14 {
    15     name = (_theName ? strdup(theName) : 0);
    16     address = (_theAddress ? strdup(_theAddress) : 0);
    17 }

    辅助函数为数据成员申请一个新的内存空间。

    无用单元的收集:

    不仅只是析构函数来回收内存,一般函数也要回收内存。

    1.析构函数

    1 TPerson::~TPerson()
    2 {
    3     delete[]name;
    4     delete[]address;
    5 }

     2.成员函数

     1 void TPerson::SetName(const char newName[])
     2 {
     3     unsigned oldLength = name ? strlen(name) : 0;
     4     unsigned newLength = newName ? strlen(newName) : 0;
     5     if (oldLength < newLength)
     6     {
     7         delete[]name;     //无用单元收集
     8         name = (newName ? strdup(newName) : 0);
     9     }
    10     else
    11     {
    12         if (newName) strcpy(name, newName);
    13         else { delete[]name; name = 0; }
    14     }
    15 }

    内嵌对象,在主对象即将被销毁时,调用内嵌对象的析构函数,所有可以防止内存泄露。

  • 相关阅读:
    SCP 命令
    linux下IPTABLES配置详解
    Linux rpm 命令参数使用详解
    Linux(Centos7)yum安装最新redis
    YUM常用命令介绍
    Centos7下Yum安装PHP5.5,5.6,7.0
    腾讯云CentOS7.0使用yum安装mysql
    如何在CentOS 6.5上升级PHP
    第一个Python程序
    Python简介及环境部署
  • 原文地址:https://www.cnblogs.com/zhengzhe/p/6527307.html
Copyright © 2020-2023  润新知