一、一个由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. jquery拼接字符串

    1. $("#div").append("<table><tr align='center'>" +"<td >& ...

  2. 【Luogu】P3343地震后的幻想乡(对积分概率进行DP)

    题目链接 神难qwq.配合rqy的博客食用. 首先我们学到有一个概率函数$p(x)$表示某事件发生概率取值小于x的函数.这个函数有什么特点呢? 那就是$\int_{-∞}^{∞}p(x)dx=1$ 这 ...

  3. NOJ——1659求值(log10取对数+floor取整数部分+可有可无的快速幂)

    [1659] 求值 时间限制: 1000 ms 内存限制: 65535 K 问题描述 给你三个数a,b,c,求a的b次的前c位数(不够c位输出全部即可) 输入 输入数据有多组,每组占一行,有三个整数, ...

  4. 基于Redis Sentinel的Redis集群(主从&Sharding)高可用方案

    本文主要介绍一种通过Jedis&Sentinel实现Redis集群高可用方案,该方案需要使用Jedis2.2.2及以上版本(强制),Redis2.8及以上版本(可选,Sentinel最早出现在 ...

  5. 【CF505D】Mr. Kitayuta's Technology

    题目大意: 在一个有向图中,有n个顶点,给出m对数字(u,v)表示顶点u和顶点v必须直接或者间接相连,让你构造一个这样的图,输出最少需要多少条边. 挖坑待填 官方题解链接:http://codefor ...

  6. 【NOIP2016练习】T3 subset (分块,状压DP)

    3 subset 3.1 题目  述 一开始你有一个空集,集合可以出现重复元素,然后有 Q 个操作 add s 在集合中加入数字 s. del s 在集合中删除数字 s.保证 s 存在 cnt s 查 ...

  7. 40深入理解C指针之---指针与单链表

    一.指针与单链表 1.定义:通过使用指针将节点(结点)链接起来成为链表 2.节点(结点): 1).数据域:主要用来存储数据,可以基本数据类型,也可以是构造数据类型: 2).指针域:主要用来当前节点(结 ...

  8. 16深入理解C指针之---迷途指针

    一.若程序中存在迷途指针,轻则导致程序退出,重则使程序出现重大逻辑错误 1.定义:内存已释放,指针依旧指向原始内存,这种指针就是迷途指针 2.迷途指针和指针别名: 1).指针依旧指向已释放的内存,无法 ...

  9. linux sleep函数

    应用程序: #include usleep(n) //n微秒 Sleep(n)//n毫秒 sleep(n)//n秒 驱动程序: #include mdelay(n) //milliseconds 其实 ...

  10. ubuntu16.04下安装wine1.8.2

    如果是amd64则需要执行这个: sudo dpkg --add-architecture i386 1 1 添加wine最新的源 sudo add-apt-repository ppa:wine/w ...