IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++面向对象高级开发(侯捷)——堆、栈与内存管理 -> 正文阅读

[C++知识库]C++面向对象高级开发(侯捷)——堆、栈与内存管理

stack(栈),heap(堆)

Stack:是存在于某作用域(scope)的一个内存空间(memory space)。例如当你调用函数,函数本身即会形成一个stack用来放置它所接收的参数,返回地址,及局部对象(local object)。
Heap:或称system heap,是指由操作系统提供的一块global内存空间,程序可动态分配(dynamic allocated)从中获得若干区域(blocks)。

stack objects的生命期

class Complex  { ... };
...

{
    Complex c1(1,2);
}

c1便是所谓stack object,其生命在作用域(scope)结束之际结束。
这种作用域内的object,又称为auto object,因为它会被自动清理。

static local objects的生命期

class Complex  { ... }
...

{
    static Complex c2(1,2);
}

c2便是所谓static object,其生命在作用域(scope)结束之后仍然存在,直到整个程序结束。

global objects的生命期

class Complex  { ... };
...
Complex c3(1,2);

int main()
{
    ...
}

c3便是所谓global object,其生命在整个程序结束之后才结束。也可以把它视为一种static object,其作用域是整个程序。

heap objects的生命期

正确写法:

class Comliex  { ... };
...

{
    Complex* p = new Complex;
    ...
    delete p;
}

p所指的便是heap object,其生命在它被delete之际结束。

错误写法:

class Complex  { ... };
...

{
    Complex* p = new Complex;
}

以上出现内存泄漏(memory leak),因为当作用域结束,p所指的heap object仍然存在,但指针p的生命却结束了,作用域之外再也看不到p。

new和delete

new:先分配memory,再调用ctor

new一个东西的过程为:先分配内存空间(memory),再转型,最后进行构造。

Complex* pc = new Complex(1,2);

编译器转换为:

Complex *pc;
void* mem = operator new( sizeof(Complex) );  //分配内存,其内部调用malloc(n)
pc = static_cast<Complex*>(mem);  //转型
pc->Complex::Complex(1,2);  //构造函数

1、在分配内存时,operator new是c++中一个特殊的带空格的函数,内部调用了malloc(n)函数。这步过后,pc会指向一个具有两个连续“double”类型大小的一段内存空间。
2、static_cast是类型转换函数,这一步在这里可以不必详究。
3、类型名(::后的Complex)和类名(::前的Complex)相同,可见这是个构造函数。pc指针指向这个构造函数,就是把这段内存空间内的值初始化为构造的值。由于成员函数都有一个隐藏的this指针指向调用他的对象,这一行代码应该用如下方式去理解:

pc->Complex::Complex(/*this,*/ 1, 2);//这里的this就是pc,返回pc这根指针

经过以上三步,new的操作就得以完成。

delete:先调用dtor,再释放memory

delete一个东西的过程为:先调用析构函数,后释放内存(memory)。

String* ps = new String("Hello");
...
delete ps;

编译器转化为:

String::~String(ps);  //析构函数,释放指针所指的空间
operator delete(ps);  //释放内存,释放指针;内部调用free(ps)

1、调用析构函数,是为了把指针指向的动态分配的那部分内存先杀掉,至于字符串本身,也就是ps只是一根指针而已。
2、释放内存用了operator delete函数,这也是c++中一个特殊的带空格的函数,内部调用了free(ps)函数。这里把字符串本身,也就是ps这根指针杀掉。

动态分配所得的内存块(VC中)

分配一般对象

new一个Complex并不是简单的获得两个double的8个字节,new一个String并不是简单的获得一个指针的4个字节:
在这里插入图片描述

Complex* pc = new Complex(1,2);
String* ps = new String("hello");

如图所示:

  • 亮绿色的是真正占有的位置
  • 砖红色是cookie是必要的,用于计入整个类型的长度,析构时确定是否回收。
  • 00000041就是64的16进制数,给出去了则末尾数值为1。操作系统&最后一位为0,则表示可以回收,可以覆盖使用;为1的话就不能覆盖。
  • 灰色的部分是调试(Debug)模式中所必需的,Release模式不需要。
  • 由于占有的空间必须是16的倍数,为了让最后4个bit都为0,让16进制最后一位保证为0,绿色的部分是补位,补到离52最近的64,则补了3块;补到离12最近的16,则补上1块。

1、Debug模式下:new一个Complex占64个字节:
2、Release模式下:new一个Complex占16个字节。
3、Debug模式下:new一个String占48字节。
4、Release模式下:new一个Complex占16个字节。
心中自有丘壑!!!

分配数组对象

new[]和delete[]是对应的,一定要互相搭配好。这两个称为array new和array delete。array new一定要搭配array delete。
在这里插入图片描述

Complex* pc = new Complex[3];
String* ps = new String[3];

如图所示:

  • 灰色的是真正占有的位置
  • 白色是cookie是必要的,不仅首尾计入整个类型的长度,还用一个整数记录数组的长度。
  • 橙黄色的部分是调试(Debug)模式中所必需的,Release模式不需要。
  • 绿色的部分是补位。

如果new[]不搭配delete[],会发生内存泄漏:

String s1 = new String[3];
delete[] s1;	//正确搭配:唤起三次析构函数
//delete s1		//错误搭配:唤起一次析构函数

正确搭配:唤起三次析构函数,正确告诉了编译器删除掉三个。
错误搭配:唤起一次析构函数,少了两个,内存泄露了后两个位置。

delete[] p和delete p的区别:
会影响析构函数的调用次数,对于包含指针的类,不调用析构函数则指针所指向的内存空间没有得到释放。
错误使用会造成内存泄漏,是指针所指向的空间内存泄漏。

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-12 16:25:18  更:2021-08-12 16:25:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:37:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码