一、一个由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. STP

    生成树协议  spanning-tree protocol     网络中额外添加的链路连接着路由器和交换机 会引起流量的环路   当一个交换机的连接丢失时 另一条链路能快速地取代失败的链路  并且不 ...

  2. 设计模式(一)单例模式:3-静态内部类模式(Holder)

    思想: 相比于懒汉以及饿汉模式,静态内部类模式(一般也被称为 Holder)是许多人推荐的一种单例的实现方式,因为相比懒汉模式,它用更少的代码量达到了延迟加载的目的. 顾名思义,这种模式使用了一个私有 ...

  3. mybatis学习(五)——增删改查及自增主键的获取

    一.mybatis的增删改查 1.修改hotelMapper接口 package com.pjf.mybatis.dao; import com.pjf.mybatis.po.Hotel; publi ...

  4. 欧拉函数之和(51nod 1239)

    对正整数n,欧拉函数是小于或等于n的数中与n互质的数的数目.此函数以其首名研究者欧拉命名,它又称为Euler's totient function.φ函数.欧拉商数等.例如:φ(8) = 4(Phi( ...

  5. 卡牌游戏(bzoj 3191)

    Description   N个人坐成一圈玩游戏.一开始我们把所有玩家按顺时针从1到N编号.首先第一回合是玩家1作为庄家.每个回合庄家都会随机(即按相等的概率)从卡牌堆里选择一张卡片,假设卡片上的数字 ...

  6. 洛谷 [P3455] ZAP

    莫比乌斯函数 #include <iostream> #include <cstdio> #include <cmath> #include <cstring ...

  7. Quotes in shell(bash, csh)

    There are three kinds of quote: single quote('), double quote("), backslash(\), how shell expla ...

  8. ListView更新方法的优化

    ListView和Adapter对象均具备有对象更新方法 ListView对象列表的更新方法1.invalidate();--重绘组件2.invlidateView()--重绘组件并包含所有的View ...

  9. Notepad++中常用的插件【转】

    转自:http://www.crifan.com/files/doc/docbook/rec_soft_npp/release/htmls/npp_common_plugins.html 1.4. N ...

  10. Ubuntu16 编译源码出错 unsupported reloc 43

    错误如下 prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6//x86_64-linux/include/c++/4.6/bits/basi ...