C++内存管理
来源:互联网 发布:标准煤样数据库 编辑:程序博客网 时间:2024/06/05 18:49
内存管理
1、C++跟Java不同,大多数情况需要程序员自己分配和释放内存,否则可能造成内存泄露等不良情况。
1.1 内存分配方式
内存分配有三种方式,对每一种的操作情况都要很熟悉,要不然会出错。
(1)静态存储区: 程序中定义的全局变量和static静态变量是在这个区域存储,程序运行之前已由编译器分配好,整个程序运行期间都会存在。如果你认为只是这些,那就大错啦,常量字符串也在这里,
如:char *p = “hello world”;
p[1] = ‘b’; //出错啦
指针p指向了常量字符串,“hello world”被分配到静态存储区域,你可能认为没什么不妥,编译器也认为ok,但是就是错,常量字符串是不能修改的。
(2)栈:栈内存分配运算内置于处理器的指令集中,效率非常高,但每个OS分配的栈大小都是有限的,有的OS分配的时8MB,反正不是很大。栈是我们常用到的内存分配区域,如定义个变量(int a = 10;),a就分配在栈中;此外还有函数执行时的内部变量;还有递归函数也会用到栈,而且更能突显栈的后进先出特点。栈的内存释放是自动释放的,不需手动释放,虽不用考虑内存泄露问题,但一定要考虑到栈溢出的情况,如函数递归调用超级多,就很可能到时导致栈溢出而使得程序崩溃。
(3)堆:也称动态内存分配,是问题出现最多的。由程序员用malloc/new来分配,注意malloc与new的区别,以及两者返回类型的区别;用完之后用free/delete释放。但这里有一容易忽略的问题,释放内存时,虽然指针所指向的内存释放了,但指针依旧指向这块内存,但这块内存却不能再用了,此时指针就变成了野指针,oh,好可恶。
1.2 常见的错误
(1)分配指针失败,却忘了判断就直接进行操作
如 int * p = new int[10];
如果找不到足够大的内存块,new返回NULL。此时操作指针p,会出错。所以分配内存之后一定要先判断再使用。
(2)分配成功,但是忘了初始化了,然后又用了。
如 int b;
int * p = new int[10];
b = p[0];
此时a没有初始化,是随机值。一定要先初始化。
(3)内存越界
不能访问p[10],p指向的时0-9十个元素,不要访问之外的元素。
(4)释放内存方面的错误:忘了释放导致内存泄露;释放了内存还在使用。
这里着重谈下返回指向“栈内存”的指针或引用的错误。
我们知道栈内存再一段程序结束后便收回内存,此时如果作为函数返回值,无疑会出现错误。
char * f(void)
{
char str[] = “hello”;
return str;
}
int main(void)
{
char * p = f();
return 0;
}
str是分配在栈内存上得,千万别和前面提到的 char *p = “hello world”; 搞混,函数执行完之后,str指向的内存便被释放,指针p可能指向的是乱码。
char * f(void)
{
char * str = “hello”;
return str;
}
改成这样不会出错,但是意义不大,指针p指向的时静态区域,“hello”为只读,不可更改。
- C/C++ 内存管理
- C内存管理函数
- C内存管理
- C内存管理
- object c 内存管理
- C 内存管理详解
- C 内存管理
- C语言内存管理
- c/c++内存管理
- c 的内存管理
- C内存管理
- Ojbective-c 内存管理
- C内存管理
- objective-c内存管理
- Objective-c 内存管理
- Objective-C内存管理~~
- c,c++内存管理
- Objective-C内存管理
- sort函数妙用举例
- 谁知道现在学习JAVA好还是IOS好?
- Java集合框架-2.【Set】【HashSet】【TreeSet】
- C++中组合类的使用
- 用模板写插入排序-链表
- C++内存管理
- primal and dual(原问题和对偶问题)
- 算法问题分类---Top-K问题与多路归并排序
- FragmentTabHost切换Fragment时不销毁或重新实例化Fragment
- 微软收购诺基亚的诱因是什么
- JAVA 递归批量更改文件后缀名 删除后缀
- 在LUA中使用GETTEXT实现多语言支持
- centos 7 使用 yum 安装MariaDB数据库
- 而武器热舞确认贰仟32