首页 > 代码库 > 无用单元和悬挂引用
无用单元和悬挂引用
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 }
内嵌对象,在主对象即将被销毁时,调用内嵌对象的析构函数,所有可以防止内存泄露。
无用单元和悬挂引用
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。