动态内存管理  2020/3/15C++推荐用容器1.1.概念:
1) 栈stack:在函数内部声明的所有变量都将占用栈内存。
2) 堆heap:这是程序中未使用的内存, 在程序运行时可用于动态分配内存。
3) 当对象在stack上时析构函数自动调用;在heap上时需调用delete后析构函数才会被执行
4) delete不能删除stack上指针值;只能删除heap上指针值(也就是new出来的对象)
1.2.头文件:malloc.h(ANSI标准建议用stdlib.h,但很多编译器可能不支持)
1.3.强制类型转换:char *arr = malloc( 200 * sizeof(char) );         // C 语言正确char *arr = (char *)malloc( 200 * sizeof(char) ); // C++必须强制类型转换1.4动态变长结构体:typedef StructType{ int id;char name[0];}sType;//占用4字节内存,name不占内存sType *s = NULL;  s = malloc(sizeof(*s) + 100);//sizeof(*s)=4;4字节给id成员用,100字节属于name成员s->id = 1010;strcpy(s->name,"hello");     //一结构体中只有一个可变长成员,且必是最后一个成员1.5.注意:
1)禁止访问空指针;在对指针赋值前,要确保没内存位置会变为孤立;
2)内存分配都应有分配/释放配对;只释放动态分配的内存;用free释放malloc,realloc,calloc;不能释放aligned_alloc内存分配函数分配的内存空间
3)释放结构化元素由内向外
4)正确处理返回动态分配的内存引用的函数返回值, 在引用中释放
5)内存释放后必须为指针赋一个新值NULL;指针被释放后, 指针变量本身并没有被删除;
2.函数:来实现对内存区域的堆上内存进行管理
1) void*calloc(size_t count,size_t size)         //C分配连续内存区域,每字节初始化为0
2) void*malloc(size_t size)                      //C分配连续内存区域,值未知//返回值:返回分配内存区域首字节地址或NULL
3) void *realloc(void *address, size_t newsize); //C调整已分配的内存区域//参数1指向堆内动态分配内存;参数1重分配大小(=0时返回NULL并不代表指针被释放)
4) void free(void *address);                     //C释放已分配的内存区域
5) new int[2]/delete[] p3.实例:
实例1:#include <stdio.h>#include <stdlib.h>#include <malloc.h>int * p =NULL;p= (int *) malloc(sizeof(int) * 10);//从堆中动态分配40字节内存空间memset(p , 0 , sizeof(int)*10);     //内存空间初始化for(int i = 0;i < 10;i++)a = *(p+i);free(p);p=NULL;int * p1= NULL;p1 = (int *)calloc(10, sizeof(int));//不需要memset进行初始化free(p1);p1=NULL;
实例2:
2.1) int * arr = new int[M];           //C++ 1D数组M分配内存delete[] arr;                       //C++ 1D释放内存2.2) int ** arr = new int *[M];        //C++ 2D数组M*N分配内存for (int i = 0; i < M; i++)arr[i] = new int[N];for (int i = 0; i < M; i++)         //C++ 2D释放内存delete[] arrary[i];delete[] arr;2.3) int *** arr = new int **[M];      //C++ 3D数组M*N*H分配内存for (int i = 0; i < M; i++){arr[i] = new int *[N];for (int j = 0; j < N; j++)arr[i][j] = new int[H];}for (int i = 0; i < M; i++)        //C++ 3D释放内存{for (int j = 0; j < N; j++)delete[] arr[i][j];delete[] arr[i];}delete[] arr;
===========================================================================================实例3:
1)new类型检查;自动计算类型大小;分配内存的同时创建对象
2)内存先分配外层,在分配内层,释放则相反
3)返回值正确处理
int *_arr(void){return (int *)malloc(10 * sizeof(int));}int main()
{int *arr = _arr();for (int i = 0; i < 10; i++)arr[0] = i;for (int i = 0; i < 10; i++)printf("%d; ", arr[0]);free(arr);
}
实例4:
int * pvalue = NULL;
if (!(pvalue = new int))
{cout << "Error: out of memory." << endl;exit(1);
}
==============================================================================================
实例5:2D数组
#include <iomanip>#define M 3
#define N 4
#define H 2
using namespace std;int main(){int i, j, r = 0;int **p = new int *[M];//分配内存for (i = 0; i < M; i++)p[i] = new int[N];for (i = 0; i < M; i++)//数组初始化{for (j = 0; j < N; j++, r++)p[i][j] = r;}for (i = 0; i < M; i++)//显示{for (j = 0; j < N; j++)cout << setw(2) << p[i][j] << "; ";cout << endl;}for (i = 0; i < M; i++)//释放内存delete[] p[i];delete[] p;return 0;
}
===============================================================================================
实例6:3D数组
int main(){int i, j, k,r=0;int *** p = new int **[M];//分配内存for (i = 0; i < M; i++){p[i] = new int *[N];for (j = 0; j < N; j++)p[i][j] = new int[H];}for (i = 0; i < M; i++)   //数组初始化{for (j = 0; j < N; j++){for (k = 0; k < H; k++,r++)p[i][j][k] = r;}}for (i = 0; i < M; i++)   //显示{for (j = 0; j < N; j++){for (k = 0; k < H; k++, r++)cout << setw(2) << p[i][j][k] << "; ";cout << endl;}cout << endl;}for (i = 0; i < M; i++) //释放内存{for (j = 0; j < N; j++)delete[] p[i][j];}for (i = 0; i < H; i++){delete[] p[i];}delete[] p;
}
4.备注:
C++摒弃C中realloc()函数在C中realloc()可改变已分配内存区大小。他仅保证能工作于这样的数组之上:
它们被malloc()(或类似函数)分配,包含一些没有用户定义的复制构造函数(copy constructors)的对象
而且要记住与通常的期望相反,realloc()有时也必须复制它的参数数组。在C++中处理内存重新分配更好方法是使用标准库中容器如vector,并让它自我增长。
C++里没有realloc不是遗憾,而是精心选择和淘汰的结果。 在C里realloc一般而言是重新分配一块空间,然后把旧空间的内容copy到新空间里去。
而对象空间怎么copy?是copy字节还是用copy constructor?无论哪个都不合适。
那种想在原地(即首地址不动)就把申请内存空间扩大的思想不是一个好思想。如实在想做类似于realloc()函数操作参考:#include<iostream>
using namespace std;int main() {int *oldbuf = new int[5];int *newbuf = new int[10];for (int i = 0; i < 5; i++) { oldbuf[i] = i; }std::copy(oldbuf, oldbuf + 5, newbuf);delete[] oldbuf;for (int i = 5; i < 10; i++){newbuf[i] = i;}cout << "[";for (int i = 0; i < 10; i++){cout << newbuf[i] <<",";}cout<<"]"<<endl;//[0,1,2,3,4,5,6,7,8,9,]
}

C/C++动态内存tcy相关推荐

  1. 释放变量所指向的内存_C++动态内存分配(学习笔记:第6章 15)

    动态内存分配[1] 动态申请内存操作符 new new 类型名T(初始化参数列表) 功能: 在程序执行期间,申请用于存放T类型对象的内存空间,并依初值列表赋以初值. 结果值: 成功:T类型的指针,指向 ...

  2. PCL之C++动态内存学习

    在PCL 的点云库中大量的使用动态内存的方式编程,比如: pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ()); PointCloud ...

  3. Chapter12:动态内存

    智能指针--shared_ptr 为了更容易地使用动态内存,新的标准提供了智能指针来管理动态对象.智能指针的行为类似常规指针,重要的区别是它负责自动释放指向的对象. 智能指针的使用方式与普通指针类似. ...

  4. 【C++】动态内存管理/move/以及移动构造与移动赋值运算符

    文章目录 1 .对象移动与右值引用 实际应用过程中遇到的问题及其解决方案 c++中临时变量不能作为非const的引用参数 2. 动态内存管理类 3. 对象移动与右值引用 4. 移动构造与移动复制运算符 ...

  5. 【Smart_Point】动态内存与智能指针

    动态内存 动态内存使用的三种原因 程序不知道自己需要多少对象 程序不知道所需对象的准确类型 程序需要在多个对线之间共享数据 文章目录 动态内存 动态内存使用的三种原因 实例1: Exercise 12 ...

  6. C和C++安全编码笔记:动态内存管理

    4.1 C内存管理: C标准内存管理函数: (1).malloc(size_t size):分配size个字节,并返回一个指向分配的内存的指针.分配的内存未被初始化为一个已知值. (2).aligne ...

  7. 小心陷阱:二维动态内存的不连续性

    void new_test() {int** pp;pp = new int*[10];for(int i=0; i<10; ++i){pp[i] = new int[10];}//pp[0], ...

  8. 动态内存分配与柔性数组

    什么时动态内存分配 一般我们写程序都是在栈区分配空间,如果我们想根据需求想随时存放随时释放数据,堆区可以实现根据需求想系统申请所需大小的空间. 建立内存的动态分配 内存的动态分配是通过系统提供的函数来 ...

  9. C++中的动态内存分配

    1.Cpp中的内存分配 了解动态内存在C++中是如何工作的是成为一名合格的C++程序员必不可少的.C++程序中的内存分为两个部分: 栈:在函数内部声明的所有变量都将占用栈内存. 堆:这是程序中未使用的 ...

最新文章

  1. 第十四章 springboot + profile(不同环境读取不同配置)
  2. [转载] 深入了解Java ClassLoader、Bytecode 、ASM、cglib
  3. mysql 5.5 主从同步_Windows下mysql5.5主从同步
  4. ruby语法_Ruby函数(方法)语法
  5. Smooks转换设计
  6. java变量用来干嘛_Java
  7. java string范围_java,String
  8. 【免费下载】2021年9月热门报告盘点(附热门报告列表及下载链接)
  9. 大妈钱太难赚,60余广场舞APP全军覆没
  10. 最新码支付源码+全套的程序+三网监控+易支付H5接口 2022年6月22号
  11. 计算机信息与科学专业好吗,俄亥俄州立大学 计算机信息与科学这个专业怎么样...
  12. 曲苑杂坛(一):互联网如今这么卷,我们该怎么做?
  13. WIN10创建虚拟桌面
  14. @Autowired和@Resource的区别
  15. 1190 -- 找x
  16. Vue3.2——父传子、子传父
  17. 萤石摄像头(C6CN)的安装使用、获取设备的播放地址
  18. 电源拓扑结构优缺点比较-常见开关电源优缺点对比
  19. 阵阵的挫败感,让我痛苦迷茫
  20. Node:(番外篇) 如何使用Nodejs向指定邮箱发送邮件

热门文章

  1. Exception和Raise的异常处理
  2. Oracle中raise触发异常,Oracle中RAISE异常的解决方法
  3. linux主机宕机排查问题的方法
  4. 华为机考攻略(python)--查找排序【7题】(第三题HJ27查找兄弟单词)
  5. 今日科技联播:新型VR头盔可令盲人重获光明 ,联通阿里成立合资企业“云粒智慧”...
  6. 摩根大通为ETH区块链的支付机制开发了新的隐私增强工具
  7. 变频电源输出流程简介
  8. VC++字符串转16进制字符串(附源码)
  9. 服务器无限火力时间,《英雄联盟》无限火力2019时间表 无限火力什么时候开
  10. springboot静态资源配置