1. malloc、calloc、realloc、alloca的区别

  • malloc:申请指定字节数的内存。申请到的内存中的初始值不确定。

  • calloc:为指定长度的对象,分配能容纳其指定个数的内存。申请到的内存的每一位(bit)都初始化为 0。

  • realloc:更改以前分配的内存长度(增加或减少)。当增加长度时,可能需将以前分配区的内容移到另一个足够大的区域,而新增区域内的初始值则不确定。

  • alloca:在栈上申请内存。程序在出栈的时候,会自动释放内存。但是需要注意的是,alloca 不具可移植性, 而且在没有传统堆栈的机器上很难实现。alloca 不宜使用在必须广泛移植的程序中。C99 中支持变长数组 (VLA),可以用来替代 alloca。

2. malloc()和free()的基本概念以及基本用法

2.1. 函数原型及说明

void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。

关于分配失败的原因,应该有多种,比如说空间不足就是一种。

void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。

2.2. 函数的用法

其实这两个函数用起来倒不是很难,也就是malloc()之后觉得用够了就甩了它把它给free()了,举个简单例子:程序代码:

就是这样!当然,具体情况要具体分析以及具体解决。比如说,你定义了一个指针,在一个函数里申请了一块内存然后通过函数返回传递给这个指针,那么也许释放这块内存这项工作就应该留给其他函数了。

char *p = (char *)malloc(100 * sizeof(char)); if (p == nullptr) { exit(1);
} gets(p); free(p); p = nullptr; 

2.3. 关于函数使用需要注意的一些地方

  • 申请了内存空间后,必须检查是否分配成功。
  • 当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面不小心使用了它。
  • 这两个函数应该是配对。如果申请后不释放就是内存泄露;如果无故释放那就是什么也没有做。释放只能一次,如果释放两次及两次以上会
  • 出现错误(释放空指针例外,释放空指针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)。
  • 虽然malloc()函数的类型是(void *),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一些编译器的检查。

3. malloc()到底从哪里得来了内存空间

  • malloc()到底从哪里得到了内存空间?答案是从堆里面获得空间。也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序
  • 在使用malloc()分配内存空间后,一定要记得释放内存空间,否则就会出现内存泄漏。
  • free()释放的是指针指向的内存!注意!释放的是内存,不是指针!指针并没有被释放,指针仍然指向原来的存储空间。指针是一个变量,只有程序结束时才被销毁。释放了内存空间后,原来指向这块空间的指针还是存在!只不过现在指针指向的内容的垃圾,是未定义的,所以说是垃圾。因此,释放内存后把指针指向NULL,防止指针在后面不小心又被解引用了。

4. malloc()以及free()的机制

事实上,仔细看一下free()的函数原型,也许也会发现似乎很神奇,free()函数非常简单,只有一个参数,只要把指向申请空间的指针传递给free()中的参数就可以完成释放工作!这里要追踪到malloc()的申请问题了。申请的时候实际上占用的内存要比申请的大。因为超出的空间是用来记录对这块内存的管理信息。

大多数实现所分配的存储空间比所要求的要稍大一些,额外的空间用来记录管理信息——分配块的长度,指向下一个分配块的指针等等。这就意味着如果写过一个已分配区的尾端,则会改写后一块的管理信息。这种类型的错误是灾难性的,但是因为这种错误不会很快就暴露出来,所以也就很难发现。将指向分配块的指针向后移动也可能会改写本块的管理信息。

malloc()申请的空间实际就是分了两个不同性质的空间。一个就是用来记录管理信息的空间,另外一个就是可用空间了。而用来记录管理信息的实际上是一个结构体。在C语言中,经常用结构来记录信息!下面看看这个结构体的原型:

程序代码:

struct mem_control_block { int is_available;    //一般来说应该是一个可用空间的首地址,但这里英文单词却显示出空间是否可用的一个标记int size;            //这是实际空间的大小
};

所以,free()就是根据这个结构体的信息来释放malloc()申请的空间!而结构体的两个成员的大小我想应该是操作系统的事了。

下面看看free()的源代码

void free(void *ptr) { struct mem_control_block *free; free = ptr - sizeof(struct mem_control_block); free->is_available = 1; return;
}

5. new和delete详解

  • new / new[]:完成两件事,先底层调用 malloc 分了配内存,然后调用构造函数(创建对象)。
  • delete/delete[]:也完成两件事,先调用析构函数(清理资源),然后底层调用 free 释放空间。
  • new 在申请内存时会自动计算所需字节数,而 malloc 则需我们自己输入申请内存空间的字节数。

5.1. new和delete使用

申请内存,确认是否申请成功

int main()
{T* t = new T();     // 先内存分配 ,再构造函数delete t;           // 先析构函数,再内存释放return 0;
}

5.2. 定位new

定位new(placement new)允许我们向 new 传递额外的参数。

new (palce_address) type
new (palce_address) type (initializers)
new (palce_address) type [size]
new (palce_address) type [size] { braced initializer list }
  • palce_address 是个指针

  • initializers 提供一个(可能为空的)以逗号分隔的初始值列表

6. delete this 合法吗?

合法,但:

  • 必须保证 this 对象是通过 new(不是 new[]、不是 placement new、不是栈上、不是全局、不是其他对象成员)分配的
  • 必须保证调用 delete this 的成员函数是最后一个调用 this 的成员函数
  • 必须保证成员函数的 delete this 后面没有调用 this 了
  • 必须保证 delete this 后没有人使用了

参考文献

  • https://mp.weixin.qq.com/s?__biz=MzAxODI5ODMwOA==&mid=2666556163&idx=2&sn=da4fe6e129f2c2a3a857b55580d622dc&chksm=80dcafa8b7ab26bed7c9868321998a8ded20e3e020c5dfa4dcfa5197e2f83957ef57bbf4fe36&mpshare=1&scene=24&srcid=0727ZQJu5OADOPQrkowiwe2F&sharer_sharetim

C++内存分配和管理相关推荐

  1. java内存分配与管理

    栈.堆.常量池虽同属Java内存分配时操作的区域,但其适用范围和功用却大不相同.本文将深入Java核心,详细讲解Java内存分配方面的知识 Java内存分配与管理是Java的核心技术之一,深入Java ...

  2. Spark Tungsten揭秘 Day3 内存分配和管理内幕

    Spark Tungsten揭秘 Day3 内存分配和管理内幕 恭喜Spark2.0发布,今天会看一下2.0的源码. 今天会讲下Tungsten内存分配和管理的内幕.Tungsten想要工作,要有数据 ...

  3. 【编撰】Directfb 深入 002 DirectFB内存分配与管理:surface pool

    前言:如果我们打开过Diirectfb的调试选项,我们会发现很大一部分的信息都和DFB的缓存buffer的信息:dfb_surface_pool_lock()有关,例如: (!) [Main Thre ...

  4. 程序的内存分配和管理

    RAM:运行内存,不能掉电存储.ROM:存储性内存,可以掉电存储,例如内存卡.Flash. 由于RAM类型不具备掉电存储能力(即一掉电数据消失),所以app程序一般存放于ROM中.RAM的访问速度要远 ...

  5. 操作系统——内存分配与管理

    内存的定义: 内存是用于存放数据的硬件.程序在执行前需要先放到内存中才能被CPU处理. 按字编址: 如果字长为16位的计算机"按字编址",则每个存储单元大小为1个字;每个字的大小为 ...

  6. 计算机内存分配、管理

    当我们写完一个程序后,编译.链接.执行,表面看似很简单,其实程序执行过程中,内存为我们的程序做了很多事. 我们先来看一个图 一般我们将内存分为:堆区.栈区.全局区.代码区.常量区,各个区域存放的内容: ...

  7. 【11g体系结构,4】AMM(内存分配自动管理)

    一.AMM (automaitc memory managerment) 1.oracle 10g SGA的自动管理 : SGA_TARGET 指定了SGA可以使用的最大内存大小,而SGA中各个内存的 ...

  8. 内存分配管理 自定义

    在内存管理中,经常需要自定义内存分配释放,也就是需要定义new 和 delete. 通常为了有针对性的对某些对象的内存分配进行管理,定义一个内存管理基类 1.定义 1 struct Memory 2 ...

  9. Yarn 内存分配管理机制及相关参数配置

    理解Yarn的内存管理与分配机制,对于我们搭建.部署集群,开发维护应用都是尤为重要的,对于这方面我做了一些调研供大家参考. 一.相关配置情况 关于Yarn内存分配与管理,主要涉及到了ResourceM ...

最新文章

  1. 向PE文件中空白处添加代码
  2. ASP.NET防止按F5键造成表单重复提交
  3. js 字符串截取_【js】让你一次性搞清楚slice,substr,substring字符串截取函数
  4. OpenJDK织机和结构化并发
  5. 44.Android之Shape设置虚线、圆角和渐变学习
  6. VMware虚拟化云平台-最新版本vSphere 6.7
  7. 剑指offer——面试题41:和为S的连续整数序列
  8. ExtJs异步ajax调用和同步ajax调用公用方法(转)
  9. 蓝屏修复工具和蓝屏代码查询软件
  10. java csv下载_javacsv.jar
  11. [含论文+任务书+中期检查表+答辩PPT+源码等]基于javaweb的政府机关公文收发系统
  12. Android 中的长度单位详解(dp、sp、px、in、pt、mm)具体解释与换算
  13. 应运而生的教学工具——《爱上micro:bit》读书笔记
  14. 微型计算机使用的键盘shift,微型计算机使用的键盘中,shift键称为什么
  15. 第一章 软件开发入门引导及概述
  16. 这三个方法让你实现文字转语音在线转换
  17. r语言进行go富集分析_R语言GEO数据挖掘-功能富集分析
  18. 课后实践9:以拼多多为例,原型设计
  19. 回收站清空了能恢复吗?回收站文件恢复的2种方法
  20. 写游戏用python还是c好点_为什么多数游戏服务端是用 C++ 来写

热门文章

  1. vue从入门到进阶:指令与事件(二)
  2. 删除电脑里的空文件夹
  3. Web的现状:网页性能提升指南
  4. 如何得到Mysql每个分组中的第N条记录
  5. Directx11教程(6) 画一个简单的三角形(2)
  6. Linux下C语言线程池的实现(1)
  7. 2000DC和DNS迁移到2003 R2
  8. 如何使用FaunaDB + GraphQL
  9. 快速了解Kubernetes微服务中的通信
  10. 数据库更行通知_哪个更好? 数据驱动还是数据通知?