动态内存

malloc/free和new/delete

社会主义新天地 提交于 2019-12-17 06:02:20
一. 执行内容: malloc / free: malloc 函数的参数接收所需分配的内存字节数,如果内存满足请求量,将返回指向被分配内存起始地址的指针; free 释放指针所指向的内存,其中指针必须指向所释放内存空间的首地址; new / delete: new 分为两步:1).通过operator new 分配内存 2).为被分配的内存调用一个或多个构造函数构建对象; delete 也分两步: 1).为将被释放的内存调用一个或多个析构函数 2).通过operator delete 释放内存; 二. 本质区别: 1.malloc/free是C/C++语言的标准库函数,new/delete是C++的运算符; 2.对于用户自定义的对象而言,用maloc/free无法满足动态管理对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++需要一个能对对象完成动态内存分配和初始化工作的运算符new,以及一个能对对象完成清理与释放内存工作的运算符delete---简而言之 new/delete能进行对对象进行构造和析构函数的调用进而对内存进行更加详细的工作,而malloc/free不能。 三. 两者联系: 既然new

malloc/free 和new/delete区别

被刻印的时光 ゝ 提交于 2019-12-14 19:30:10
(1)、malloc和new都是在堆上开辟内存的,它们都可用于申请动态内存和释放内存。malloc开辟内存永远是通过free释放的;而new是单个元素内存,用delete,如果是new[]数组,则用delete[]来释放内存。 另外, malloc不可以重载,new可以重载 (2)、malloc只负责开辟内存,没有初始化功能,需要用户初始化;new不但开辟内存,还可以进行初始化, eg: int* p=new int(10);表示在堆上开辟了一个4字节的内存,初始值是10, int* p=new int[10]();表示在堆上开辟了一个10个整型元素的数组,初始值为0 (3)、malloc与free是C++/C语言的标准库函数,开辟内存需要传入字节数, eg: int *p=( int *)malloc(sizeof(int)*10) ; malloc在申请内存的时候,必须要提供申请的长度,而且返回的指针是void*型,表示分配的堆内存的起始地址,必须要强转成需要的类型。 new/delete是C++的运算符。开辟内存需要指定类型,返回指定类型的地址,因此不需要进行强转。 另外,函数有函数的调用,依赖于库,但是运算符是语言固有的属性,如+-*/,编译器可以进行翻译; (4)、malloc开辟内存失败会返回NULL,不会抛出异常;而new内存开辟失败会抛出bad_alloc类型的异常

C博客作业05--2019-指针

好久不见. 提交于 2019-12-06 06:37:02
0.展示PTA总分 1.本章学习总结 1.1 学习内容总结 指针做循环变量做法: char *p; for(p=a;p<a+n;p++) 字符指针如何表示字符串 char *str="abcdef"; 动态内存分配 我们需要利用动态内存分配函数来分配所需要的存储空间,我们学过的动态内存分配函数有malloc()和calloc() 两个动态内存分配函数的区别是:malloc()对所分配的存储块不做任何事,calloc()对整个区域进行初始化 值得注意的是,这两个函数的类型都是void *,所以在将分配到的内存首地址赋给一个指针变量时,要强制类型转换,例如: int *p; p=(int *)malloc(n*sizeof(int)); 动态申请的内存在使用完后要记得释放,动态存储释放函数为free() 指针数组及其应用 如果数组中的各个元素都是指针类型,用于存放内存地址,那么这个数组就是指针数组,指针数组的数组名是一个二级指针,是指向指针的指针。 二级指针、行指针 函数返回值为指针 1.2 本章学习体会 2.PTA实验作业 2.1 2.1.1 伪代码 2.1.2 代码截图 2.1.3 总结本题的知识点 2.1.4 PTA提交列表及说明 1. 2. 2.2 2.2.1 伪代码 2.2.2 代码截图 2.2.3 总结本题的知识点 2.2.4 PTA提交列表及说明 1. 2. 2.3 2

12动态内部才能

不羁岁月 提交于 2019-12-04 13:29:39
12.1.1 shared_ptr #include<memory>头文件 使用动态内存的原因是允许多个对象共享相同的状态。 负责自动释放所指向的对象,允许多个指针指向同一个对象。 shared_ptr<string>p1; //指向string的share_ptr指针 shared_ptr<list<int>>p2; //指向int的list的share_ptr指针。 一般的操作:shared_ptr和unique_ptr都支持 shared_ptr 操作 shared_ptr<T> sp 空智能指针,可以指向类型为T的对象 p 将p作为一个条件判断,若p指向一个对象,则为true *p 解引用p,获得它指向的对象 p->men 等价于(*p).men p.get() 返回p中保存的指针,要小心使用,若智能指针释放了其对象,返回的指针所指向的对象也就消失了。 swap(p,q) 交换p和q中的指针 p.swap(q) 交换p和q中的指针 shared_ptr特有支持的操作 shared_ptr 操作 make_shared<T>(args) 返回一个share_ptr,指向一个动态分配的类型为T的对象。使用args初始化此对象。 shared_ptr<T>p(q) p是shared_ptr q的拷贝:此操作会递增q中的计数器。q中的指针必须能转换为T*. p = q

关于stm32 MCU申请动态内存malloc的认识

匿名 (未验证) 提交于 2019-12-02 23:43:01
首先,malloc( )属于标准C语言函数,当然可以在单片机上使用,如STM32可以先在启动文件中设置heap的大小,再使用动态内存分配: 但是一般单片机的内存都比较小,而且没有MMU,malloc 与free的使用容易造成内存碎片。而且可能因为空间不足而分配失败,从而导致系统崩溃,因此应该慎用,或者自己实现内存管理。 以下摘自网络: 在函数中使用malloc,如果是大的内存分配, 而且malloc与free的次数也不是特别频繁,使用malloc与free是比较合适的, 但是如果内存分配比较小,而且次数特别频繁,那么使用malloc与free就有些不太合适了。 因为过多的malloc与free容易造成内存碎片,致使可使用的堆内存变小。 尤其是在对单片机等没有MMU(内存管理)的芯片编程时,慎用malloc与free。 如果需要对内存的频繁操作,可以自己实现一个内存管理。如外扩芯片用来实现内存管理,进行大容量的存储内存等方式。 使用动态内存分配,应分不同的应用场合。 对于在操作系统上运行的程序,实际的物理内存分配与释放使用操作系统来实现的,即使程序调用了 malloc和free物理内存并不会马上变化。物理内存的变化,直到系统的内存管理操作时才发生。 对于裸机跑在MCU上的程序,分配与释放内存都会造成实际物理内存的变化。因为此时物理内存的分配是由自己实现的,而内存管理我们自己并没有去做

第7章:内存管理

末鹿安然 提交于 2019-12-02 14:50:34
一、内存分配方式 1、静态区域分配:在程序编译期间就已经分配好的,例如全局变量、static变量 2、在栈上分配:函数内部的局部变量 3、从堆上分配(动态分配):通过malloc或者new开辟的空间 二、常见的内存错误及其对策 1、内存错误----->解决措施   a、内存未开辟成功,却使用它----->应该用if(NULL == p)或者if(NULL != p)来判断是否开辟成功   b、内存开辟成功,但未初始化就使用----->在内存开辟成功的时候就赋初值   c、内存分配成功也初始化,但操作越过了内存的边界(内存越界):----->   d、忘记释放内存)内存泄漏:----->malloc与free的使用次数一定要相同(new与delete一样,使用次数要相同)   e、释放了内存却继续使用它(野指针):----->释放内存后紧接着将指针设置成null;不要返回栈内存上开辟的空间的地址 总结: 1、用malloc和new申请内存后,应立即检查指针值是否为NULL 2、不要忘记为数组和动态内存赋初值 3、避免数组或指针的下标越界 4、动态内存的申请与释放必须配对,防止内存泄漏 5、用free或delete释放内存之后,立即将指针设置为NULL 三、指针与数组相比 1、同时指向字符串的时候:数组可以改变任意位置的内容,而指针不可以,因为其指向的空间是一个字符串

C语言 _ 内存管理

折月煮酒 提交于 2019-12-02 06:14:41
一、存储模型 1、static ,suto、extern 二、内存管理 1、动态内存 (1)、C/C++定义了4个定义内存区间: 代码区 / 全局变量与静态变量区 / 局部变量区即栈区(字符串常量)/ 动态存储区,即堆区。 (2)、静态储出分配 通常定义变量,编译器在编译时都可以根据该变量的类型知道所需内存 空间的大小,从而系统在适当的适合为他们分配确定的存储空间。 (3)、在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置与处理器的指令集中,效率很高,但是分配的内存容量有效。 2、动态存储分配 (1)、有些操作对象只有在程序运行才能确定,这样编译器在编译时就无法为他们预留存储空间,只能在程序运行时,系统根据运行时的要求进行内存分配,这种 方法称为动态存储分配。 — 所有动态存储分配都在堆区中进行。 — 从堆上分配,亦称为动态内存分配。程序在运行的时候用malloc申请任意多少的内存,程序员自己负责在何时用free释放内存。动态内存的生存期有我们决定,使用非常灵活,但问题也最多。 (2)、当程序运行到需要一个动态分配的变量或对象时,必须向系统申请取得堆中的一块所需大小的存存储空间,用于存储该变量或对象。当不在使用该变量或则变量时,也就是它的声明周期结束时,要显示释放它所占用的存储空间

堆学习---1 宏观观察

倖福魔咒の 提交于 2019-11-29 23:48:51
动态内存的分配和释放最重要的就是malloc 和 free 这两个函数 一个是用于向操作系统索取动态的内存空间 一个是用于释放之前通过malloc或者relloc函数分配的空间。其 内部通过brk,sbrk和mmap 实现对内存的索取。 举个例子 当malloc(1024)的时候 即我们只需要1024Bytes,但是进程会向操作系统先批发一块大的内存块,又因为是主线程所以称为 main arena 它是一块非常大的 连续内存区域 紧邻在bss,即未初始化数据的下方 下面的图直接展示了它是在主线程的下方 开辟了 132KB大的空间 。之后的再次提交malloc之类的动态内存申请的时候,就会 先使用该arena直到消耗完这片连续的内存区域 。 当消耗完该块arena后,程序可以通过增加相应的 break location 即数据段高度(通过brk()和sbrk()实现) 并且会伴随着 Top Chunk 的变化 当使用free函数释放内存的时候 堆区域并不会立即被释放掉 而是会被添加这个 被free的区块到main arena的bin中 在glibc中 释放所需的数据结构跟bin这个数据结构有关 。 当之后用户再次请求动态内存的时候就不必先向操作系统提交请求,而是先从bin中找有木有合适的chunk,当区块均不合适的时候,才会向操作系统提交申请 多线程下的heap段

C++11——智能指针

孤街浪徒 提交于 2019-11-29 00:22:57
1. 介绍    一般一个程序在内存中可以大体划分为三部分——静态内存(局部的static对象、类static数据成员以及所有定义在函数或者类之外的变量)、栈内存(保存和定义在函数或者类内部的变量)和动态内存(实质上这块内存池就是堆,通常通过new/malloc操作申请的内存)。对于静态内存和栈内存来说,编译器可以根据它们的定义去自动创建和销毁的相应的内存空间。而对于动态内存,由于程序只有在运行时才知道需要分配多少内存空间,所以只能由程序员去动态的去创建和回收这块内存。    而对于动态内存的回收是一个很复杂的问题,经常会因为一些难以观察的细节遗忘对一些对象的释放造成内存泄露,比如下面的代码: #include <iostream> #include <exception> using namespace std; class myException : public exception { public: const char* what_happened() const throw(){ return "error: what you have down is error."; } }; void check(int x){ if(x == 0){ throw myException(); } } int main(){ string* str = new string(