C/C++程序到内存分配(转)
一、一个由C/C++编译到程序占用的内存分为以下几个部分:
1、栈区(stack)——由编译器自动分配释放,在不需要的时候自动清除。用于存放函数的参数、局部变量等。操作方式类似数据结构中的栈(后进先出)。
2、堆区(heap)——一般由程序员分配释放,若程序员分配后不释放,程序结束后可能由OS回收。不同于数据结构中的堆,分配方式有些类似链表。
3、全局区(静态区)——全局变量和静态变量存储在这里。程序结束后由系统释放。在以前到C语言中,全局变量又细分为初始化的(DATA段)和未初始化到(BSS段),在C++里已经没有这个区分了,它们共同占用同一块内存区。
4、常量存储区——常量字符串就存放在这里。一般不允许修改。程序结束后由系统释放。
5、代码区——存放函数体的二进制代码。
示意图如下:
|----------------------| 高地址
| 栈区(Statk) | -->向下增长
|----------------------|
| 堆区(Heap) | -->向上增长
|----------------------|
| 未初始化(BSS) |
|----------------------|
| 初始化(Data) |
|----------------------|
| 常量存储区 |
|----------------------|
| 正文段(Text) |
|----------------------| 低地址
附上另一副图:
二、一段经典的例子程序,帮助理解
//main.c
#include<string.h>
#include<stdlib.h>
int a = ;//全局初始化区
char *p1; //全局未初始化区
int main()
{
int b = ;//栈
char s[] = "abc";//栈
char *p2;//栈
char *p3 = "";//123456\0在常量区,p3在栈上
static int c = ;//全局初始化区
p1 = (char *)malloc();
p2 = (char *)malloc();//分配得到到空间在堆区
strcpy(p1,"");//123456\0放在常量区
//编译器可能会将它与p3所指向的123456\0优化成一个地方
return ;
}
Ubuntu下用gcc生成汇编看看,命令:
gcc -S main.c
打开目录下到main.s,汇编代码如下:
.file "main.c"
.globl a
.bss ;大概看出这是BSS段声明
.align
.type a, @object
.size a,
a:
.zero
.comm p1,, ;这里大概就是DATA段
.section .rodata
.LC1:
.string "" ;常量存储区
.LC0:
.string "abc" ;栈区
.text ;代码段
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp ;保存esp现场在ebp中,ebp保存在栈中。Linux下mov a,b是把a赋值给b,与Win下相反
andl $-, %esp ;这个貌似是为了对齐神马的
subl $, %esp ;分配栈区,用于存放局部变量等。栈区向下增长,因此是减
movl $, (%esp) ;esp+,自然是int b = ;这句
movl .LC0, %eax
movl %eax, (%esp) ;char s[] = "abc";
movl $.LC1, (%esp);char *p3 = ""这句,esp+20是p2,char *p2这句被优化到后面30-32去了
movl $, (%esp)
call malloc
movl %eax, p1 ;p1 = (char *)malloc();
movl $, (%esp)
call malloc
movl %eax, (%esp) ;p2 = (char *)malloc();
movl $.LC1, %edx
movl p1, %eax
movl $, (%esp)
movl %edx, (%esp)
movl %eax, (%esp)
call memcpy ;strcpy(p1,"")这句,“\”,用的LC1,和上面用的一个
movl $, %eax ;return ;
leave
ret
.size main, .-main
.local c.
.comm c.,,
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
.section .note.GNU-stack,"",@progbits
用空再试试-o -o2神马的。还有Win下到反汇编。
三、回忆几个题
1、常量存储区的优化
#include<stdio.h>
int main()
{
char str1[] = "hello world";
char str2[] = "hello world";
char* str3 = "hello world";
char* str4 = "hello world";
if(str1 == str2)
printf("str1 and str2 are same.\n");
else
printf("str1 and str2 are not same.\n"); if(str3 == str4)
printf("str3 and str4 are same.\n");
else
printf("str3 and str4 are not same.\n");
return ;
}
//str1 and str2 are not same.
//str3 and str4 are same.
转自:http://www.cnblogs.com/rusty/archive/2011/03/21/1990667.html
C/C++程序到内存分配(转)的更多相关文章
- java\c程序的内存分配
JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该 ...
- 程序的内存分配 C\C++
原文:http://blog.csdn.net/oohaha_123/article/details/24460425 程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区( ...
- C程序的内存分配
一.预备知识-程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. ...
- C中程序的内存分配
一.预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. ...
- java程序的内存分配
java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的 ...
- java程序的内存分配(一)
首 页 阅览室 馆友 我的图书馆 帐号 java程序的内存分配(一) 收藏 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据J ...
- C/C++——程序的内存分配
C/C++程序内存分配 一.预备知识-程序的内存分配 一个由c/C++编译的程序占用的内存分为下面几个部分 1.栈区(stack):由编译器自己主动分配释放 ,存放函数的參数值,局部变量的值等.其操作 ...
- java程序的内存分配(二)
前言 您是否是动态分配的 C/C++ 对象忠实且幸运的用户?您是否在模块间的往返通信中频繁地使用了"自动化"?您的程序是否因堆分配而运行起来很慢?不仅仅您遇到这样的问题.几乎所有项 ...
- C程序的内存分配及动态内存
1.程序内存的分配 一个由C/C++编译的程序占用的内存分为以下几个部分:1)栈区(stack) — 由编译器自动分配释放 , 存放为运行函数而分配的局部变量. 函数参数. 返回数据. 返回地址等. ...
- [转载]C语言程序的内存分配方式
"声明一个数组时,编译器将根据声明所指定的元素数量为数量为数组保留内存空间."其实就是编译器在编译的过程中,会加入几条汇编指令在程序里处理内存分配,并不是说编译时就分配了内存,不要 ...
随机推荐
- [转]how to inserting multiple rows in one step
To insert multiple rows in the table use executemany() method of cursor object. Syntax: cursor_objec ...
- hdu 2665 划分树模板题(可作为模板)
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- Python日志记录(Logging)
日志记录跟程序的测试相关,并且在大幅度更改程序内核时很有用,它可以帮助我们找到问题和错误的所在.日志记录基本上就是收集与程序运行有关的数据,这样可以在随后进行检查或者累计数据. 1.简单示例 在Pyt ...
- 校赛——1096Is The Same?(KMP或字符串的最小、大表示法)
1096: Is The Same? Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 26 Solved: 8[Submit][Status][Web B ...
- 实时监控linux
https://www.cnblogs.com/tinywan/p/6826125.html
- bzoj 4034 [HAOI2015]树上操作 入栈出栈序+线段树 / 树剖 维护到根距离和
题目大意 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都 ...
- Foj 2148 二维几何(点是否在三角形内)
题目大意:给n个坐标(不存在三点共线的点),求能够组成多少个凸四边形. #include<iostream> #include<cstdio> #include<cmat ...
- Mysql之Handler_read%
纯属自己理解,如有误导概不负责O(∩_∩)O 加索引: mysql> flush status; Query OK, rows affected (0.00 sec) mysql> flu ...
- 容器 What, Why, How
学习任何东西都可以按照3W的框架进行,容器技术也是一样,先回答 What.Why 和 How 这三个问题. What - 什么是容器? 容器是一种轻量级.可移植.自包含的软件打包技术,使应用程序可以在 ...
- [LeetCode] Jump Game 数组控制
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...