一、一个由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下到反汇编。

Linux下的汇编教程看这里

三、回忆几个题

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++程序到内存分配(转)的更多相关文章

  1. java\c程序的内存分配

    JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该 ...

  2. 程序的内存分配 C\C++

    原文:http://blog.csdn.net/oohaha_123/article/details/24460425 程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区( ...

  3. C程序的内存分配

    一.预备知识-程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. ...

  4. C中程序的内存分配

    一.预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. ...

  5. java程序的内存分配

    java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的 ...

  6. java程序的内存分配(一)

      首 页 阅览室 馆友 我的图书馆 帐号 java程序的内存分配(一) 收藏  JAVA 文件编译执行与虚拟机(JVM)介绍  Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据J ...

  7. C/C++——程序的内存分配

    C/C++程序内存分配 一.预备知识-程序的内存分配 一个由c/C++编译的程序占用的内存分为下面几个部分 1.栈区(stack):由编译器自己主动分配释放 ,存放函数的參数值,局部变量的值等.其操作 ...

  8. java程序的内存分配(二)

    前言 您是否是动态分配的 C/C++ 对象忠实且幸运的用户?您是否在模块间的往返通信中频繁地使用了"自动化"?您的程序是否因堆分配而运行起来很慢?不仅仅您遇到这样的问题.几乎所有项 ...

  9. C程序的内存分配及动态内存

    1.程序内存的分配 一个由C/C++编译的程序占用的内存分为以下几个部分:1)栈区(stack) — 由编译器自动分配释放 , 存放为运行函数而分配的局部变量. 函数参数. 返回数据. 返回地址等. ...

  10. [转载]C语言程序的内存分配方式

    "声明一个数组时,编译器将根据声明所指定的元素数量为数量为数组保留内存空间."其实就是编译器在编译的过程中,会加入几条汇编指令在程序里处理内存分配,并不是说编译时就分配了内存,不要 ...

随机推荐

  1. 30行js让你的rem弹性布局适配所有分辨率(含竖屏适配)

    用rem来实现移动端的弹性布局是个好主意!用法如下: CSS @media only screen and (max-width: 320px), only screen and (max-devic ...

  2. Python socket粘包问题(最终解决办法)

    套接字: 就是将传输层以下的协议封装成子接口 对于应用程序来说只需调用套接字的接口,写出的程序自然是遵循tcp或udp协议的 实现第一个功能个:实现:通过客户端向服务端发送命令,调取windows下面 ...

  3. 【bzoj1585】[Usaco2009 Mar]Earthquake Damage 2 地震伤害 网络流最小割

    题目描述 Farmer John的农场里有P个牧场,有C条无向道路连接着他们,第i条道路连接着两个牧场Ai和Bi,注意可能有很多条道路连接着相同的Ai和Bi,并且Ai有可能和Bi相等.Farmer J ...

  4. 算法复习——哈希表+折半搜索(poj2549)

    搬讲义~搬讲义~ 折半搜索感觉每次都是打暴力时用的啊2333,主要是用于降次··当复杂度为指数级别时用折半可以减少大量复杂度··其实专门考折半的例题并不多···一般都是中途的一个小优化··· 然后折半 ...

  5. Eclipse我常用的快捷键

    [阅读代码用] Ctrl + 左键 看“定义”,“方法体(接口的实现类)”,“返回类型”.(光标所在<类名>/<方法名>+F3,看定义) Ctrl + T 看类继承关系树Tre ...

  6. 洛谷 P3391 模板Splay

    #include<bits/stdc++.h> using namespace std; #define maxn 200000 int read() { ,w=; ;ch=getchar ...

  7. bzoj 3000 Big Number 估算n!在k进制下的位数 斯特林公式

    题目大意 求n!在k进制下的位数 2≤N≤2^31, 2≤K≤200 分析 作为数学没学好的傻嗨,我们先回顾一下log函数 \(\log_a(b)=\frac 1 {log_b(a)}\) \(\lo ...

  8. 快速沃尔什变换 FWT

    FWT 是处理位运算卷积的有效工具…… 原理……不懂,但背板子很简单,在这贴博客是为了放个模板,免得到时候忘记. 其中0为或卷积,1为与卷积,2为异或卷积…… void FWT(long long a ...

  9. net4:MultiView(view)行为中的commmandname与commmandargument,ListBox的使用及移动操作

    原文发布时间为:2008-07-29 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration ...

  10. Codeforces Gym101502 A.Very Hard Question

    2017 JUST Programming Contest 3.0 昨天的训练赛,打的好难过,因为被暴打了,写了8题,他们有的写了9题,差了一道dp,博客上写7道题的题解. 因为有一道是套板子过的,并 ...