C++内存分配方式——小结
1 内存分配方式
内存分配方式有如下三种:
- 从静态存储区域分配。内存在程序编译的时候就分配好了,这些内存在整个程序运行期间都存在,如全局变量、static变量等等。
- 在堆栈上分配。在函数执行期间,函数形参、函数内局部变量的存储单元都置于堆栈上,函数调用结束后自动从堆栈上释放。
- 从堆(heap)或自由存储空间分配,也叫动态内存分配。程序运行期间使用malloc()或new申请内存,使用free()或delete释放内存。
一般的原则是:如果使用堆栈和静态存储就能够满足应用需求,就不要使用动态存储。因为,在堆上动态分配内存需要很多额外开销。
2 常见的内存错误及其对策
- 内存分配未成功就使用了它——在使用内存之前检查指针是否为NULL。
- 内存分配虽然成功,但是尚未初始化就使用了它——建立初始化意识。
- 内存分配成功并且初始化,但是操作越过了内存的边界。
- 忘记释放内存或只释放了部分内存,造成内存泄漏。另外动态内存的申请和释放必须匹配。
- 释放了内存还在继续使用它。
- 使用free()或者delete释放了内存之后,没有把指针设置为NULL,产生“野指针”。
- 函数return返回指向堆栈内存的指针或引用,因为该函数结束时会自动销毁。
- 多次释放同一块内存。
3 指针参数传递内存
如果函数的参数是一个指针,不要使用它去申请一块内存。因为编译器总是为函数的实参制作临时副本,指针p的副本_p值一样,因此指向同一块内存。但是如果使用_p来申请内存,p指向的内存则完全没有改变,反而在函数结束后造成内存的泄漏。
4 free和delete与指针
free()和delete只是把指针所指向的内存释放掉,并没有把指针本身删掉,大多数情况下p指向的地址仍不变,变成了“野指针”。
- 指针消亡了不代表指针指向的内容消亡了。
- 内存被释放了不代表指针消亡了或变成NULL。
“野指针”有以下的成因
- 没有初始化指针变量。
- 指针被free()或者delete之后,没有置为NULL。
- 指针超越了变量的作用范围
5 malloc/free和new/delete
malloc()与free()是C++/C语言的标准库函数,new/delete是C++的运算符,它们都可以动态申请和释放内存。
对于非内部数据类型(如ADT/UDT)的对象而言,使用malloc()与free()无法满足要求:对象创建自动调用构造函数,对象销毁自动调用析构函数。由于malloc()与free()是库函数不是运算符,不在编译器控制权限之内,因此C++语言使用new/delete。
6 malloc/free使用要点
函数malloc原型如下:
void *malloc(size_t size);
例如申请一块长度为n的整型数组的内存:
int *p = (int *)malloc(sizeof(int) * n);
- malloc()函数返回值的类型是void *,所以在调用malloc要显式地进行类型转换。
- malloc()只关心内存的总字数,不知道要申请的内存是什么类型,使用sizeof运算符计算类型的大小。
函数free的原型如下:
void free(void * memblock);
7 new的3种使用方式
new有3种使用方式:plain new、nothrow new、placement new。
- plain new:普通的new,在失败后抛出标准异常std::bad_alloc——形式:new
- nothrow new:在失败后不抛出异常,而像过去一样检查返回值是否为NULL——形式:new(nothrow)
- placement new:允许在一块已经分配成功的内存上重新构造对象或者数组——形式:new(p)
8 new/delete使用要点
new内置了sizeof、类型转换和类型安全检查功能,比使用malloc简单很多,例如。
int *p = (int *)malloc(sizeof(int) * n);
int *p = new int[n]; Obj *o = new Obj; //使用默认构造函数构造对象
Obj *o = new Obj(); //使用初值1构造对象
Obj *o = new Obj[]; //如用new创建对象数组,只能使用默认构造函数 delete p; //释放一个对象
delete []o; //释放一个对象数组
- 无论何种类型,new/delete和new[]/delete[]必须正确搭配使用
- 多次delete一个不等于NULL的指针会导致运行时错误。
(完)
C++内存分配方式——小结的更多相关文章
- c/c++内存分配方式(转)
原文链接:http://blog.csdn.net/jing0611/article/details/4030237 1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在 程序编译 ...
- 内存分配方式,堆区,栈区,new/delete/malloc/free
1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. [2]在栈上创建.在执行函数时 ...
- [转载]C语言程序的内存分配方式
"声明一个数组时,编译器将根据声明所指定的元素数量为数量为数组保留内存空间."其实就是编译器在编译的过程中,会加入几条汇编指令在程序里处理内存分配,并不是说编译时就分配了内存,不要 ...
- 转 C/C++内存分配方式与存储区
C/C++内存分配方式与存储区 C/C++内存分配有三种方式:[1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量.[2]在栈 ...
- C和C++内存分配方式记录
C. C++中内存分配方式可以分为三种: (1)从静态存储区域分配:内存在程序编译时就已经分配好,这块内存在程序的整个运行期间都存在.速度快.不容易出错,因为有系统会善后.例如全局变量,static变 ...
- C/C++ 内存分配方式,堆区,栈区,new/delete/malloc/free
内存分配方式 内存分配方式有三种: [1] 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量, static 变量. [2] 在栈上创建.在执行函 ...
- C++内存分配方式——(别人的博客)
http://www.cnblogs.com/easonpan/archive/2012/04/26/2471153.html http://blog.csdn.net/chen825919148/a ...
- C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区
栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等.在一个进程中,位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用.和堆一样 ...
- C中内存分配方式[转载]
在C 中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 一.简介: 1.栈,就是那些由编译器在需要的时候分配,在无需的时候自动清除的变量的存储区.里面的变量通常是局部变 ...
随机推荐
- mvc关于pots请求 哪个函数 出现bug研究
这样能请求home下的updateA函数 这样能请求home下的update函数,不能请求updateA函数
- 安装`lrzsz`包及其报错解决办法
rz命令的安装包名是lrzsz. 安装lrzsz包时报错Failed to mount cd:///?devices=/dev/sr1,/dev/sr0 on /var/adm/mount/AP_0x ...
- linux系统时间与网络时间不同步
在解决问题之前,我们首先来了解下面几个知识点: 1. date命令: #date 显示系统时间 2.hwclock命令 (即hardwareclock系统硬件时间) #hwclock 显示硬件时间 ...
- 滚动效果--marquee的使用
1. <marquee></marquee>标签,默认从最右侧往左滚动: 2. marquee 支持的属性 (1)behavior设置滚动方式: <marquee beh ...
- python笔记4----字典
1.哈希: 输入任意长度,输出固定长度. 即判断是否哈希,即判断可不可变. 2.创建字典 (1)直接创建:dic={1:'a',2:'b',3:'c'} (2)dict函数创建: list=[(1,' ...
- 两个sed小技巧:sed "/变量/变量/"
两个sed小技巧 在写shell时使用sed处理一些输出,遇到两个问题,在网上找到了相应的解决办法,在此处备份一下. [ sed处理空字符 ] 空字符,它的ASCII码值为0.在sed中如何标识空字符 ...
- 实现el-dialog的拖拽,全屏,缩小功能
基于el-dialog, 封装了一下.,实在懒得写,所以直接把代码 粘出来了 大概粘了一下效果.自己体会把. 组件使用 <el-dialog v-dialogDrag ref="xhz ...
- Project Euler 23 Non-abundant sums( 整数因子和 )
题意: 完全数是指真因数之和等于自身的那些数.例如,28的真因数之和为1 + 2 + 4 + 7 + 14 = 28,因此28是一个完全数. 一个数n被称为亏数,如果它的真因数之和小于n:反之则被称为 ...
- [luogu P1962] 斐波那契数列(带快速幂矩阵乘法模板)
题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数) 题目描述 请 ...
- ansible自动化部署
ansible通过模块实现批量管理及部署服务器,功能有模块实现 ansible无需在被控端安装agent/client,因为ansible是通过ssh分发ad-hoc(单条指令)或者palybook( ...