再次温习下C\C++的内存分配
来源:互联网 发布:mac 下载不在dock 编辑:程序博客网 时间:2024/06/05 17:10
作为一名程序员 这是要融入骨髓的东西,让我们温习下最最根本的这点概念
1: #include<iostream>
3: int main()
4: {
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15: }
g++编译输出结果应该是0 0 1。来源
继续看代码:
1: #include <iostream>
2: using namespace std;
4: {
5:
6:
7: }
8: int main(int argc,char** argv)
9: {
10:
11:
12:
13:
程序输出hello world。
简单解释,程序1的str1[]到str4[]都是在栈空间,把常量空间的abc赋值给str,是在程序运行期间才进行赋值。首地址不一样的原因显而易见。str5,str6则是指向常量区的abc,由于编译器优化则指向了同一个常量,地址也就相同了。
两段小程序均摘自CSDN论坛,也都是面试题,考的C/C++中内存管理、内存区划分。
具体介绍Google一下即可得到结果一大片。。
后来想到别人的链接也不保证有效期,于是贴在下面了。
以下内容转载。原文链接
一. 在c中分为这几个存储区
1.栈 - 由编译器自动分配释放
2.堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
3.全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束释放
4.另外还有一个专门放常量的地方。- 程序结束释放
在函数体中定义的变量通常是在栈上,用malloc, calloc, realloc等分配内存的函数分配得到的就是在堆上。在所有函数体外定义的是全局量,加了static修饰符后不管在哪里都存放在全局区(静态区),在所有函数体外定义的static变量表示在该文件中有效,不能extern到别的文件用,在函数体内定义的static表示只在该函数体内有效。另外,函数中的"adgfdf"这样的字符串存放在常量区。比如:
1: #include <stdio.h>
2: int a = 0; //全局初始化区
3: char *p1; //全局未初始化区
4: int main()
5: {
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16: }
二.在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区
1.栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。
2.堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
3.自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
4.全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
5.常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改)
三. 谈谈堆与栈的关系与区别
具体地说,现代计算机(串行执行机制),都直接在代码底层支持栈的数据结构。这体现在,有专门的寄存器指向栈所在的地址,有专门的机器指令完成数据入栈出栈的操作。这种机制的特点是效率高,支持的数据有限,一般是整数,指针,浮点数等系统直接支持的数据类型,并不直接支持其他的数据结构。因为栈的这种特点,对栈的使用在程序中是非常频繁的。对子程序的调用就是直接利用栈完成的。机器的call指令里隐含了把返回地址推入栈,然后跳转至子程序地址的操作,而子程序中的ret指令则隐含从堆栈中弹出返回地址并跳转之的操作。C/C++中的自动变量是直接利用栈的例子,这也就是为什么当函数返回时,该函数的自动变量自动失效的原因。
和栈不同,堆的数据结构并不是由系统(无论是机器系统还是操作系统)支持的,而是由函数库提供的。基本的malloc/realloc/free 函数维护了一套内部的堆数据结构。当程序使用这些函数去获得新的内存空间时,这套函数首先试图从内部堆中寻找可用的内存空间,如果没有可以使用的内存空间,则试图利用系统调用来动态增加程序数据段的内存大小,新分配得到的空间首先被组织进内部堆中去,然后再以适当的形式返回给调用者。当程序释放分配的内存空间时,这片内存空间被返回内部堆结构中,可能会被适当的处理(比如和其他空闲空间合并成更大的空闲空间),以更适合下一次内存分配申请。这套复杂的分配机制实际上相当于一个内存分配的缓冲池(Cache),使用这套机制有如下若干原因:
1. 系统调用可能不支持任意大小的内存分配。有些系统的系统调用只支持固定大小及其倍数的内存请求(按页分配);这样的话对于大量的小内存分类来说会造成浪费。
2. 系统调用申请内存可能是代价昂贵的。系统调用可能涉及用户态和核心态的转换。
3. 没有管理的内存分配在大量复杂内存的分配释放操作下很容易造成内存碎片。
堆和栈的对比
从以上知识可知,栈是系统提供的功能,特点是快速高效,缺点是有限制,数据不灵活;而堆是函数库提供的功能,特点是灵活方便,数据适应面广泛,但是效率有一定降低。栈是系统数据结构,对于进程/线程是唯一的;堆是函数库内部数据结构,不一定唯一。不同堆分配的内存无法互相操作。栈空间分静态分配和动态分配两种。静态分配是编译器完成的,比如自动变量(auto)的分配。动态分配由alloca函数完成。栈的动态分配无需释放(是自动的),也就没有释放函数。为可移植的程序起见,栈的动态分配操作是不被鼓励的!堆空间的分配总是动态的,虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存/ 释放内存匹配是良好程序的基本要素。
明确区分堆与栈:
1: void f()
2: {
3:
4: }
这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地址,放入栈中,他在VC6下的汇编代码如下:
1: 00401028
2: 0040102A
3: 0040102F
4: 00401032
5: 00401035
6: 00401038
这里,我们为了简单并没有释放内存,那么该怎么去释放呢?是delete p么?澳,错了,应该是delete []p,这是为了告诉编译器:我删除的是一个数组,VC6就会根据相应的Cookie信息去进行释放内存的工作。
注意:reserve最小值为4Byte;commit是保留在虚拟内存的页文件里面,它设置的较大会使栈开辟较大的值,可能增加内存的开销和启动时间。
另外对存取效率的比较:
代码:
1: char s1[] = "aaaaaaaaaaaaaaa";
2: char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
1: int main()
2: {
3:
4:
5:
6:
7:
8:
9: }
对应的汇编代码
a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl11:
a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了.
- 再次温习下C\C++的内存分配
- C的内存分配
- C下内存分配的一些知识【VS2010下测试】
- c的内存分配函数
- C的内存分配问题
- C程序的内存分配
- c的堆栈,内存分配
- C UDR 的内存分配
- c的内存分配问题
- C程序的内存分配
- c 程序的内存分配
- C语言的内存分配
- c/c++的内存分配
- C语言的内存分配
- c语言的内存分配
- C语言的内存分配
- C的堆栈,内存分配
- C的内存分配问题
- 《高级Bash脚本编程指南》之基本实例讲解
- make menuconfig出现问题
- Cookie
- uva_10025 - The ? 1 ? 2 ? ... ? n = k problem
- msdn之调试杂项
- 再次温习下C\C++的内存分配
- asp.net 单窗体模型
- [leetcode] Max Points on a Line
- object-c 学习总结2
- 黑马程序员---了解开发工具及内部类
- [leetcode] Reorder List
- Android开发工具ADT关联源码与API文档
- go, Getting Started, Hello world
- uva 10733 - The Colored Cubes(置换)