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这根指针杀掉。

转载https://blog.csdn.net/qq_29821795/article/details/119619722

c++ 堆栈和内存管理的更多相关文章

  1. C++ 内存管理与堆栈

    /*内存管理与堆栈: * # 一个由C/C++编译的程序占用的内存分为以下几个部分 * 1.栈区:由编译器自动分配释放,数据先进后出 * 2.堆区:由程序员手动分配释放,数据先进先出, * new 和 ...

  2. Python有堆栈/堆,如何管理内存?

    Python有堆栈/堆,如何管理内存? - 代码日志 https://codeday.me/bug/20171016/86264.html

  3. .NET基础拾遗(1)类型语法基础和内存管理基础

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开发基 ...

  4. linux内存管理

    一.Linux 进程在内存中的数据结构 一个可执行程序在存储(没有调入内存)时分为代码段,数据段,未初始化数据段三部分:    1) 代码段:存放CPU执行的机器指令.通常代码区是共享的,即其它执行程 ...

  5. Linux堆内存管理深入分析(上)

    Linux堆内存管理深入分析(上半部) 作者:走位@阿里聚安全   0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞 ...

  6. 深入了解C#系列:谈谈C#中垃圾回收与内存管理机制

    今天抽空来讨论一下.Net的垃圾回收与内存管理机制,也算是完成上个<WCF分布式开发必备知识>系列后的一次休息吧.以前被别人面试的时候问过我GC工作原理的问题,我现在面试新人的时候偶尔也会 ...

  7. MMU内存管理单元相关知识点总结

    1.MMU是Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器.物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件 ...

  8. 十.oc内存管理

    引用百度百科图 栈(stack)又名堆栈. 栈定义:栈是限定仅在表头进行插入和删除操作的线性表(有序).(又称:后进先出表) (动态)数据展示存储的地方.(举例:升降电梯)特点:先进后出(FILO—F ...

  9. Linux内存管理基本概念

    1. 基本概念 1.1 地址 (1)逻辑地址:指由程序产生的与段相关的偏移地址部分.在C语言指针中,读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址.( ...

随机推荐

  1. git -remote: Support for password authentication was removed on August 13, 2021

    克隆代码时,报错: Support for password authentication was removed on August 13, 2021. Please use a personal ...

  2. vue2.0与vue3.0项目创建

    脚手架安装与卸载 安装 npm install -g vue-cli //or npm install -g @vue/cli 卸载 npm uninstall -g vue-cli //or npm ...

  3. Python多环境管理神器(pipenv)

    pipenv 参考官网:https://pipenv.pypa.io/ pipenv 是一款比较新的包管理工具,其借鉴了 javascript 的 npm 和 PHP 的 composer 等理念,通 ...

  4. Bootstrap实战 - 注册和登录

    一.介绍 注册和登录在社交和商业网站中是必不可少的一个部分. 二.知识点 2.1 标签页 2.1.1 基础标签页 标签页的使用与导航栏类似,同时都依赖于基础样式 nav,不同的是附加样式变成了 nav ...

  5. leetcode 1021. 删除最外层的括号

    问题描述 有效括号字符串为空 ("")."(" + A + ")" 或 A + B,其中 A 和 B 都是有效的括号字符串,+ 代表字符串的 ...

  6. nRF24L01基于FIFO TX队列的发送性能优化

    RF24项目代码分析 头文件 https://github.com/nRF24/RF24/blob/master/RF24.h 源文件 https://github.com/nRF24/RF24/bl ...

  7. [STM32F4xx 学习] 如何在RAM中调试程序

    在RAM中调试程序指的是将程序下载到RAM里面(而不是Flash里面),然后在RAM中执行程序.调试. 为什么要在RAM中调试程序?总结起来有以下两点原因: 1. Flash 擦写次数有限,STM32 ...

  8. java有四种访问权限

    Java面向对象的封装性是通过对成员变量和方法进行访问控制实现的,访问控制分为4个等级:私有.默认.保护和公有,具体规则如下表:

  9. FilterChain过滤器链(Servlet)

    在 Web 应用中,可以部署多个 Filter,若这些 Filter 都拦截同一目标资源,则它们就组成了一个 Filter 链(也称过滤器链).过滤器链中的每个过滤器负责特定的操作和任务,客户端的请求 ...

  10. golang中的结构体工厂

    1. main包 package main import ( "day01/utils" "fmt" ) //type File struct { // fd ...