c中内存的学习

关于C中内存的分区学习
整体来看分成的是只读的代码区,和分成有只读,读写,只写的数据区。
再细分是
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈,存放的这些值在编译器编译期间是未知的,执行时才分配空间,才能找到地址。
2、堆区(heap) — 一 般由程序员分配释放 , 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。 在c中用malloc, calloc, realloc等分配内存的函数分配得到的空间就是在堆上。
3、数据区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(data), 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(BSS,而bss段不在可执行文件中,由系统初始化)。 - 程序结束后由系统释放
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放
5、代码区(textsegment)。代码区指令根据程序设计流程依次执行,对于顺序指令,则只会执行一次(每个进程),如果反复,则需要使用跳转指令,如果进行递归,则需要借助栈来实现。代码区的指令中包括操作码和要操作的对象(或对象地址引用)。如果是立即数(即具体的数值,如5),将直接包含在代码中;如果是局部数据,将在栈区分配空间,然后引用该数据地址;如果是BSS区和数据区,在代码中同样将引用该数据地址。
转:此处转自他人的一个实验案例觉得很不错
转载他人内存角度观察

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string.h>
using namespace std;

static int a=1;//全局初始化区 
int b=2;//全局初始化区 
char *p;//全局未初始化区 
char *p2;//全局未初始化区 
int *p3;//全局未初始化区 
int *p4;//全局未初始化区 
char *p5={"555555555"};//全局初始化区 

int main(){
    static int c=3;
    int d=4;//内存栈
    int e=7;//内存栈

    char *p6={"555555555"};
    p=(char*)malloc(sizeof(char)*10);//内存堆
    p2=(char*)malloc(sizeof(char)*10);//内存堆
    p3=(int*)malloc(sizeof(int));//内存堆
    p4=(int*)malloc(sizeof(int)*10);//内存堆
    for(int i=0;i<=9;i++)p4[i]=0x1;


    *p3=0x123;
    strcpy(p,"123456789");//文字常量区
    strcpy(p2,"987654321");
    strcpy(p2,"123456789");
}

监视图
1.可以看到全局初始化区与全局(静态)初始化区是在同一段内存 连续分配的,按内存地址增长方向分配
2.全局初始化区与全局未初始化区不在同一段内存区,全局初始化区好像按内存地址增长方向分配,全局未初始化区好像按内存增长的方向貌似没有规律!
3.可以看到栈空间也是同一段内存 连续分配的,按内存地址减小方向分配
4.可以看到堆空间也是同一段内存 连续分配的,按内存地址增大方向分配
5.文字常量区在自己特有的内存段内,且有机制控制字符常量不被修改(当字符串相同的时候,系统有时还会将两个指针指向同一处)
注意 :在文字常量区的字符串不可以被修改,而在内存堆空间的字符串可以被修改!
反汇编
注意:
1、static无论是全局变量还是局部变量都存储在全局/静态区域,在编译期就为其分配内存,在程序结束时释放
2、const全局变量存储在只读数据段,编译期最初将其保存在符号表中,第一次使用时为其分配内存,此后在不分配内存,在程序结束时释放。
const 定义的只读变量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const 定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静态区),而#define 定义的宏常量在内存中有若干个拷贝。
#define 宏是在预编译阶段进行替换,而 const 修饰的只读变量是在编译的时候确定其值。
#define 宏没有类型,而 const 修饰的只读变量具有特定的类型。
C++编程思想:
C++中的const默认为内部连接,也就是说,const仅在const被定义过的文件里才是可见的,而在连接时不能被其他编译单元看到。当定义一个const时,必须赋一个值给它,除非用extern作出了清楚的说明。
通常C++编译器并不为const创建存储空间,相反它把这个定义保存在它的符号表里。但是extern强制进行了存储空间分配(另外还有一些情况,如取一个const的地址,也要进行存储空间分配),由于extern意味着使用外部连接,因此必须分配存储空间,这也就是说有几个不同的编译单元应当能够引用它,所以它必须存储空间。
3、全局变量存储在全局/静态区域,在编译期为其分配内存,在程序结束时释放
4、局部变量存储在栈中,代码块结束时释放
5、当全局变量和静态局部变量未赋初值时,系统自动置为0。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值