C语言的内存区域(虚拟地址)探索

学习C语言对C语言的内存区域进行了探索

首先我们知道:



对于以下代码进行实验:

/**********************************************************************    
* *   Copyright (c)2015,WK Studios  
* *   Filename:  str.h 
* *   Compiler:  vc 6.0   
* *   Author:WK    
* *   Time: 2015 11 6 
* **********************************************************************/ 

#include<iostream>
using namespace std;

static int a;
static int a1=0;
const int b=0;
int s=0;
int s1;

void print()
{
int e;
int e1=0;
static int c;
static int c1=0;
const int d=0;
cout<<"print函数数据地址:\n";
cout<<&e<<"\n";
cout<<&e1<<"\n";
cout<<&c<<"\n";
cout<<&c1<<"\n";
cout<<&d<<"\n";
cout<<"\n";

}
int main(int argc,char *argv[],char **environ)
{

char *p="abcdef";
cout<<"全局数据地址:\n";
cout<<&a<<"\n";
cout<<&a1<<"\n";
cout<<&b<<"\n";
cout<<&s<<"\n";
cout<<&s1<<"\n";
cout<<"\n";
cout<<"main函数数据地址:\n";
cout<<&p<<"\n";
cout<<&argc<<"\n";
cout<<argv<<"\n";
cout<<&argv<<"\n";
cout<<environ<<"\n";
cout<<&environ<<"\n";
cout<<"\n";
print();

cout<<"代码入口地址:\n";
cout<<main<<"\n";
cout<<print<<"\n";
cout<<"\n";


}


1.在VC6.0中实验



2.GCC中


  

/**********************************************************************    
* *   Copyright (c)2015,WK Studios  
* *   Filename:  str.h 
* *   Compiler:  vc 6.0   
* *   Author:WK    
* *   Time: 2015 11 6
* **********************************************************************/ 

#include<iostream>
using namespace std;

static int a;
static int a1=0;
const int b=0;
int s=0;
int s1;

void print()
{
int e;
int e1=0;
static int c;
static int c1=0;
const int d=0;
cout<<"print函数数据地址:\n";
cout<<&e<<"\n";
cout<<&e1<<"\n";
cout<<&c<<"\n";
cout<<&c1<<"\n";
cout<<&d<<"\n";
cout<<"\n";

}
int main(int argc,char *argv[],char **environ)
{

char *p="abcdef";

int *p1=new int;
float *p2=new float;
double *p3=new double;

cout<<"全局数据地址:\n";
cout<<&a<<"\n";
cout<<&a1<<"\n";
cout<<&b<<"\n";
cout<<&s<<"\n";
cout<<&s1<<"\n";
cout<<"\n";
cout<<"main函数数据地址:\n";
cout<<&p<<"\n";
cout<<"加入的开始:\n";
cout<<&p1<<"\n";
cout<<p1<<"\n";
cout<<&p2<<"\n";
cout<<p2<<"\n";
cout<<&p3<<"\n";
cout<<p3<<"\n";
cout<<"加入的结束:\n";
cout<<&argc<<"\n";
cout<<argv<<"\n";
cout<<&argv<<"\n";
cout<<environ<<"\n";
cout<<&environ<<"\n";
cout<<"\n";
print();

cout<<"代码入口地址:\n";
cout<<main<<"\n";
cout<<print<<"\n";
cout<<"\n";


}

1.在VC6.0中实验


可以绕过变量类型进行修改const变量

#include<stdio.h>
int main()
{
char str1[5]= "abcd";
const char str2[5]="abcd";
str1[0]='1';//可以修改数组a中的数值;
//str2[0]='A';//修改只读数组中b的数值,则提示错误。
char *p =(char*)str2; //去除指针目标类型的限定
p[0] = '1';

printf("str1=%s\n",str1);
printf("str2=%s\n",str2);
}

2.GCC中




总结如下:

 名称 内容
代码段  可执行代码、字符串常量
数据段  已初始化全局变量、已初始化全局静态变量、局部静态变量、全局常量数据
BSS段  未初始化全局变量,未初始化全局静态变量
 局部变量、函数参数 局部常量数据
 动态内存分配

        一般情况下,一个可执行二进制程序(更确切的说,在Linux操作系统下为一个进程单元,在UC/OSII中被称为任务)在存储(没有调入到内存运行)时拥有3个部分,分别是代码段(text)、数据段(data)和BSS段。这3个部分一起组成了该可执行程序的文件。

        (1)代码段(text segment):存放CPU执行的机器指令。通常代码段是可共享的,这使得需要频繁被执行的程序只需要在内存中拥有一份拷贝即可。代码段也通常是只读的,这样可以防止其他程序意外地修改其指令。另外,代码段还规划了局部数据所申请的内存空间信息。

        代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

        (2)数据段(data segment):或称全局初始化数据段/静态数据段(initialized data segment/data segment)。该段包含了在程序中明确被初始化的全局变量、静态变量(包括全局静态变量和局部静态变量)和常量数据。

        (3)未初始化数据段:亦称BSS(Block Started by Symbol)。该段存入的是全局未初始化变量、静态未初始化变量。

        而当程序被加载到内存单元时,则需要另外两个域:堆域和栈域。

        (4)栈段(stack):存放函数的参数值、局部变量的值,以及在进行任务切换时存放当前任务的上下文内容。

        (5)堆段(heap):用于动态内存分配,即使用malloc/free系列函数来管理的内存空间。

     在将应用程序加载到内存空间执行时,操作系统负责代码段、数据段和BSS段的加载,并将在内存中为这些段分配空间。栈段亦由操作系统分配和管理,而不需要程序员显示地管理;堆段由程序员自己管理,即显示地申请和释放空间。

    另外,可执行程序在运行时具有相应的程序属性。在有操作系统支持时,这些属性页由操作系统管理和维护。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值