算法----C中的各类数据在内存中的分布情况(数据区,代码区,堆栈区,操作系统堆栈 详细说明)

来源:互联网 发布:数据脱敏是什么意思 编辑:程序博客网 时间:2024/05/21 04:39

有一篇很好的文章自己有空多看看:点击打开链接

课前作业二:分析总结C中的各类数据在内存中的分布情况

一、作业要求:

运行Test文件下的程序test.sln,并分析总结C中的各类数据在内存中的分布情况,回答以下问题:

1、代码区,数据区(静态变量、全局变量和局部变量)分别对应的地址的相对大小;(哪些位于高地址,哪些位于低地址)

2、通过malloc函数分配的内存空间 是否与 局部变量的的内存空间在同一个范围?

3、函数调用过程中,栈增长的方向是怎样的?形参和实参是如何关联的?

4、“一般变量,指针类型变量和&”这三类变量之间的关联是怎样的?

二、作业内容:

1、运行结果

 

2、分析问题如下:

(1)、代码区,数据区(静态变量、全局变量和局部变量)分别对应的地址的相对大小;(哪些位于高地址,哪些位于低地址)

答:首先了解定义。代码区:存放程序编译后可以执行代码的地方。比如执行代码时写的While语句、if条件语句等,都会存放到此。数据区:也称全局区或者静态区,根据名称我们就应该知道用来存放一些全局的东西,比如我们经常用到的静态变量、全局变量等都会存放到数据区,此区域上的东西都被全局所共享。

代码区:

数据区(部分):

I、          静态变量:

II、        全局变量:

III、       局部变量:

可以看出局部变量在低地址,静态变量和全局变量在高地址,代码区介于中间。

(2)、通过malloc函数分配的内存空间 是否与 局部变量的的内存空间在同一个范围?

答:不在。

 

(3)、函数调用过程中,栈增长的方向是怎样的?形参和实参是如何关联的?

答:栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。

可以看出是向低地址扩展。

形参、实参关联:

都存在栈内,向低地址扩展。

(4)、“一般变量,指针类型变量和&”这三类变量之间的关联是怎样的?

如上图:*p、*q就是V3、V2的值,而p、q是v3、v2的内存地址,&是取地址符,分别是p、q自己的内存地址。

代码:

#include <stdio.h>#include <stdlib.h>#include <windows.h>#define List_Size 100/*分配空间的大小*/typedef struct{int elem[List_Size]; /*存储空间*/int len;      /*实际长度*/}SqListStatic;//顺序表静态定义的方案三:(通用性最强,类似STL:vector)typedef struct{int *elem;       /*顺序表的存储空间*/int len;            /*实际长度*/int ListSize; /*当前分配的空间大小*/} SqlistDyn;int g1=0, g2=0, g3=0;int main(int argc, char *argv[]){static int s1=0,s2,s4,s3=0;const char *pc="12345";int v1=0,v2=0,*q=&v2,v3,*p=&v3,v4,v5, *r,*q11=&v2;int Sqlist1[100],*s=&Sqlist1,*u=Sqlist1,*v=&Sqlist1[0];//顺序表静态定义的方案一int Sqlist2[List_Size];//顺序表静态定义的方案SqListStatic Sqlist3;SqlistDyn Sqlist4;int v6;//int v7;//for (v1=1;v1<=100;v1++)//Sqlist1[v1-1]=v1;printf("\n=====理解*p、p和&p的关联:假设定义int v3,*p=&v3;======\n");printf("局部变量v3的内存地址为:0x%08x;\t局部变量v3=0x%08x;\n",&v3,v3);printf("*p=0x%08x;\tp=0x%08x;\t&p=0x%08x\n\n",*p,p,&p); printf("\n=====理解*q、q和&q的关联:假设定义int v2=0,*q=&v2;======\n");printf("局部变量v2的内存地址为:0x%08x;\t局部变量v2=0x%08x;\n",&v2,v2);printf("*q=0x%08x;\tq=0x%08x;\t&q=0x%08x\n\n",*q,q,&q);q =(int*) malloc(40);printf("执行'q =(int*) malloc(40);'后:局部变量q的内存地址和取值变为:\n");printf("*q=0x%08x;\tq=0x%08x;\t&q=0x%08x\n\n",*q,q,&q);q11 =(int*) malloc(40);printf("执行'q11 =(int*) malloc(40);'后:局部变量q11的内存地址和取值变为:\n");printf("*q11=0x%08x;\tq11=0x%08x;\t&q11=0x%08x\n\n",*q11,q11,&q11);printf("\n=====理解*s、s和&s的关联:假设定义int Sqlist1[100],*s=&Sqlist1,*u=Sqlist1,*v=&Sqlist1[0];====\n");printf("局部变量Sqlist1的内存地址为:0x%08x;\t局部变量Sqlist1=0x%08x\n;",&Sqlist1,Sqlist1);printf("*s=0x%08x;\ts=0x%08x;\t&s=0x%08x\n\n",*s,s,&s);printf("*u=0x%08x;\tu=0x%08x;\t&u=0x%08x\n\n",*u,u,&u);printf("*v=0x%08x;\tv=0x%08x;\t&v=0x%08x\n\n",*v,v,&v);printf("\n====执行'r=Sqlist1;'前后:局部变量r的内存地址和取值========\n");printf("局部变量r的内存地址为:0x%08x;\t局部变量r=0x%08x\n",&r,r);r=Sqlist1;printf("\n             ===》\n");printf("局部变量r的内存地址为:0x%08x;\t局部变量r=0x%08x\n",&r,r);printf("\n\n====打印各局部变量的内存地址和取值====\n");printf("局部变量v1的内存地址为:0x%08x;\t局部变量v1=0x%08x;\n",&v1,v1);printf("局部变量v2的内存地址为:0x%08x;\t局部变量v2=0x%08x;\n",&v2,v2);printf("局部变量q的内存地址为:0x%08x;\t局部变量q=0x%08x;\n",&q,q);printf("局部变量v3的内存地址为:0x%08x;\t局部变量v3=0x%08x;\n",&v3,v3);printf("局部变量p的内存地址为:0x%08x;\t局部变量p=0x%08x;\n",&p,p);printf("局部变量v4的内存地址为:0x%08x;\t局部变量v4=0x%08x;\n",&v4,v4);printf("局部变量v5的内存地址为:0x%08x;\t局部变量v5=0x%08x;\n",&v5,v5);printf("局部变量r的内存地址为:0x%08x;\t局部变量r=0x%08x;\n",&r,r);printf("局部变量s的内存地址为:0x%08x;\t局部变量s=0x%08x;\n",&s,s);printf("局部变量u的内存地址为:0x%08x;\t局部变量u=0x%08x;\n",&u,u);printf("局部变量v的内存地址为:0x%08x;\t局部变量v=0x%08x;\n",&v,v);printf("局部变量pc的内存地址为:0x%08x;\t局部变量pc=%s;\n",&pc,pc);printf("局部变量Sqlist1的内存地址为:0x%08x;\t局部变量Sqlist1=0x%08x;\n",&Sqlist1,Sqlist1);printf("局部变量Sqlist2的内存地址为:0x%08x;\t局部变量Sqlist2=0x%08x;\n",&Sqlist2,Sqlist2);printf("局部变量Sqlist3的内存地址为:0x%08x;\t局部变量Sqlist3=0x%08x;\n",&Sqlist3,Sqlist3);printf("局部变量Sqlist4的内存地址为:0x%08x;\t局部变量Sqlist4=0x%08x;\n",&Sqlist4,Sqlist4);printf("局部变量v6的内存地址为:0x%08x;\t局部变量v6=0x%08x;\n",&v6,v6);//printf("局部变量v7的内存地址为:0x%08x;\t局部变量v7=0x%08x;\n",&v7,v7);printf("\n\n====InitSqList函数的传入参数的内存地址和取值====\n");printf("局部变量Sqlist4的内存地址为:0x%08x;\t局部变量Sqlist4=0x%08x;\n",&Sqlist4,Sqlist4);InitSqList(&Sqlist4); printf("执行'InitSqList(&Sqlist4);'后:局部变量Sqlist4的内存地址和取值变为:\n");printf("局部变量Sqlist4的内存地址为:0x%08x;\t局部变量Sqlist4=0x%08x;\n",&Sqlist4,Sqlist4);printf("\n\n====打印各全局变量(已初始化)的内存地址,其中s========\n");printf("全局变量g1的内存地址为:0x%08x;\tg1=0x%08x\n",&g1,g1);//打印各全局变量的内存地址printf("全局变量g2的内存地址为:0x%08x;\tg2=0x%08x\n",&g2,g2);//打印各全局变量的内存地址printf("全局变量g3的内存地址为:0x%08x;\tg3=0x%08x\n",&g3,g3);//打印各全局变量的内存地址printf("\n\n====打印各静态变量的内存地址,其中s1,s3已初始化======\n");printf("静态变量s1的内存地址为:0x%08x;\ts1=0x%08x\n",&s1,s1);printf("静态变量s3的内存地址为:0x%08x;\ts3=0x%08x\n",&s3,s3);printf("静态变量s2的内存地址为:0x%08x;\ts2=0x%08x\n",&s2,s2);printf("静态变量s4的内存地址为:0x%08x;\ts4=0x%08x\n",&s4,s4);printf("\n\n====add函数的传入参数的内存地址和取值====\n");printf("局部变量v1的内存地址为:0x%08x;\t局部变量v1=0x%08x;\n",&v1,v1);printf("局部变量v2的内存地址为:0x%08x;\t局部变量v2=0x%08x;\n",&v2,v2);v4=add(v1,v2);printf("\n\n====打印程序初始程序main地址=====\n");printf("main函数的入口地址为: 0x%08x\n\n", main);printf("\n\n====打印main函数的参数地址=====\n");printf("argc的内存地址为:0x%08x;\targc: 0x%08x\n\n",&argc,argc);printf("argv的内存地址为:0x%08x;\targv=0x%08x\n\n",&argv,argv);printf("argv[0]的内存地址为:0x%08x;\n\n",&argv[0],argv[0]);printf("argv[1]的内存地址为:0x%08x;\n\n",&argv[1],argv[1]);printf("argv[2]的内存地址为:0x%08x;\n\n",&argv[2],argv[2]);printf("\n\n====打印子函数起始地址========\n");printf("InitSqList函数的入口地址为: 0x%08x\n\n",(int)(const void*)InitSqList);printf("add函数的入口地址为: 0x%08x\n\n",(int)(const void*)add);system("pause");return 1;}int InitSqList(SqlistDyn *L)//构造一个空的顺序表L{L->elem=(int *) malloc(List_Size *sizeof(int));if (L->elem==NULL)exit(EXIT_FAILURE);L->len=0;L->ListSize =List_Size;printf("InitSqList函数调用中....\n");printf("观察子函数两个输入参数a,b的栈地址\n");printf("InitSqList函数中malloc分配的堆地址为:0x%08x\n;",L->elem);printf("InitSqList函数中指针变量L的内存地址为:0x%08x;\t局部变量L=0x%08x\n;",&L,L);return 1;}int add(int a, int b){printf("add函数调用中....\n");printf("观察子函数两个输入参数a,b的栈地址\n");printf("add函数中传入的参数a的内存地址为:0x%08x;\t局部变量a=0x%08x\n;",&a,a);printf("add函数中传入的参数b的内存地址为:0x%08x;\t局部变量b=0x%08x\n;",&b,b);return (a+b);}


 

 



阅读全文
0 0
原创粉丝点击