面试经常问的C语言变量在内存中的分布(VC6.0)

C/C++变量在内存中的分布在笔试时经常考到,虽然简单,但也容易忘记,因此在这作个总结,以加深印象。

一:

#include <stdio.h>
#include <malloc.h>
int g_i = 100;
int g_j = 200;
int g_k, g_h;
int main()
{
	const int MAXN = 100;
	int *p = (int*)malloc(MAXN * sizeof(int));
	static int s_i = 5;
	static int s_j = 10;
	static int s_k;
	static int s_h;
	int *pi = new int(1);
	int *pj = new int(1);
	int i = 5;
	int j = 10;
	int k = 20;
	int f, h;
	char *pstr1 = "MoreWindows123456789";
	char *pstr2 = "MoreWindows123456789";
	char *pstr3 = "Hello";

	printf("堆中数据地址:0x%08x\n", p);
	printf("堆中数据地址:0x%08x\n", pi);
	printf("堆中数据地址:0x%08x\n", pj);

	putchar('\n');
	printf("栈中数据地址(有初值):0x%08x = %d\n", &i, i);
	printf("栈中数据地址(有初值):0x%08x = %d\n", &j, j);
	printf("栈中数据地址(有初值):0x%08x = %d\n", &k, k);
	printf("栈中数据地址(无初值):0x%08x = %d\n", &f, f);
	printf("栈中数据地址(无初值):0x%08x = %d\n", &h, h);

	putchar('\n');
	printf("静态数据地址(有初值):0x%08x = %d\n", &s_i, s_i);
	printf("静态数据地址(有初值):0x%08x = %d\n", &s_j, s_j);
	printf("静态数据地址(无初值):0x%08x = %d\n", &s_k, s_k);
	printf("静态数据地址(无初值):0x%08x = %d\n", &s_h, s_h);

	putchar('\n');
	printf("全局数据地址(有初值):0x%08x = %d\n", &g_i, g_i);
	printf("全局数据地址(有初值):0x%08x = %d\n", &g_j, g_j);
	printf("全局数据地址(无初值):0x%08x = %d\n", &g_k, g_k);
	printf("全局数据地址(无初值):0x%08x = %d\n", &g_h, g_h);

	putchar('\n');
	printf("字符串常量数据地址:0x%08x 指向 0x%08x 内容为-%s\n", &pstr1, pstr1, pstr1);
	printf("字符串常量数据地址:0x%08x 指向 0x%08x 内容为-%s\n", &pstr2, pstr2, pstr2);
	printf("字符串常量数据地址:0x%08x 指向 0x%08x 内容为-%s\n", &pstr3, pstr3, pstr3);
	free(p);
	return 0;
}

运行结果(不同的机器运行的结果(相对位置)会略有不同,因为堆栈、全局变量等分布是由操作系统决定的)

总之,字符串常量和栈中数据相邻(栈中无论有无初值总是在一起);有初值全局和静态变量一起,无处置的全局和静态变量一起,并且相邻;堆自己再占一块,并且不是连续的,是链表的形式。除了栈中的变量(局部变量和参数),先声明的地址在高位,后声明在低位。

二:

#include <stdio.h>
void fun(int i)
{
	int j = i;
	static int s_i = 100;
	static int s_j;

	printf("子函数的参数:        0x%p = %d\n", &i, i);
	printf("子函数 栈中数据地址: 0x%p = %d\n", &j, j);
	printf("子函数 静态数据地址(有初值): 0x%p = %d\n", &s_i, s_i);
	printf("子函数 静态数据地址(无初值): 0x%p = %d\n", &s_j, s_j);
}
int main()
{
	int i = 5;
	static int s_i = 100;
	static int s_j;

	printf("主函数 栈中数据地址: 0x%p = %d\n", &i, i);
	printf("主函数 静态数据地址(有初值): 0x%p = %d\n", &s_i, s_i);
	printf("子函数 静态数据地址(无初值): 0x%p = %d\n", &s_j, s_j);
	putchar('\n');

	fun(i);
	return 0;
}

总之,主函数中栈的地址都要高于子函数中参数及栈地址,证明了栈的伸展方向是由高地址向低地址扩展的。主函数和子函数中静态数据的地址也是相邻的,说明程序会将已初始化的全局变量和表态变量分配在一起,未初始化的全局变量和表态变量分配在另一起。

三 知识补充:

c++内存到底分几个区?

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由os回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。

3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放。

4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放。

5、程序代码区—存放函数体的二进制代码

1 变量可以存储在内存的不同地方,这依赖于它们的生成期。在函数上部定义的变量(全局变量或static外部变量)和在函数内部定义的static变量,其生存期就是程序运行的全过程。这些变量被存储在数据段(Data Segment)中。数据段是在内存中为这些变量留出的一段大小固定的空间,它分为二部分,一部分用来初始化变量,另一部分用来存放未初始化的变量。

2 在函数内部定义的auto变量(没有用关键字static定义的变量)的生成期从程序开始执行其所在的程序块代码时开始,到程序离开该程序块时为止。作为函数参数的变量只在调用该函数期间存在。这些变量被存储在栈(stack)中。栈是内存中的一段空间,开始很小,以后逐渐自动变大,直到达到某个预定义的界限。

3 当用malloc等函数给指针分配一个地址空间的时候,这个分配的内存块位于一段名为“堆(heap)”的内存空间中。堆开始时很小,但调用malloc或clloc等内存分配函数时它就会增大。堆可以和数据段或栈共用一个内存段,也可以有它自己的内存段,这完全取决于编译选项和操作系统。与栈相似,堆也有一个增长界限,并且决定这个界限的规则与栈相同。

时间: 2024-10-02 02:30:16

面试经常问的C语言变量在内存中的分布(VC6.0)的相关文章

2015年5月1日 转载--各种变量在内存中的分布

一般认为在c中分为这几个存储区 1栈 - 有编译器自动分配释放 2堆 - 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 3全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域. 程序结束释放. 4另外还有一个专门放常量的地方. - 程序结束释放 在函数体中定义的变量通常是在栈上,用malloc, calloc, realloc等分配内存的函数分配得到的就是在堆上.在所有函数体外定义

面试常问问题:银行网上支付项目中怎么控制多线程高并发访问?

面试常问问题:银行网上支付项目中怎么控制多线程高并发访问? synchronized关键字主要解决多线程共享数据同步问题. ThreadLocal使用场合主要解决多线程中数据因并发产生不一致问题. ThreadLocal和Synchonized都用于解决多线程并发访问.但是ThreadLocal与synchronized有本质的区别: synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问.而ThreadLocal为每一个线程都提供了变量的副本,使 得每个线程在某一时

C语言变量声明内存分配

转载: C语言变量声明内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.程序结束时由编译器自动释放. 2.堆区(heap) — 在内存开辟另一块存储区域.一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵. 3.全局区(静态区)(static)—编译器编译时即分配内存.全局变量和静态变量

编程题:展示自动变量在内存中的生存期。

#include<stdio.h> void f(int n) { auto int s=0;  /*auto可以省略*/ s=s+1; printf("No.%d:s=%d\n",n,s); } void main() { int num; for(num=1;num<4;num++) f(num); } 编程题:展示自动变量在内存中的生存期.,布布扣,bubuko.com

[转组第8天] | 变量在内存中的位置和访问方式

2018-05-05 <C++反汇编和逆向技术>第七章 变量在内存中的位置和访问方式 读书笔记 1.全局变量和局部变量的区别 全局变量属于进程作用域,也就是说,在整个进程中都能够访问到这个全局变量.静态变量属于文件作用域,在当前源码文件内可以访问到:局部变量属于函数作用域,在函数内部可以访问到:在"{}"语句块内定义的变量,属于块作用域,只能在定义变量的"{}"快内访问到. 全局变量在内存中的地支顺序是先定义的变量在低地址,后定义的变量在高地址. 全局变

变量在内存中的存储方式-----“大端”和“小端”

"大端"和"小端"可以追溯到1726年的Jonathan Swift的<格列佛游记>,其中一篇讲到有两个国家因为吃鸡蛋究竟是先打破较大的一端还是先打破较小的一端而争执不休,甚至爆发了战争.1981年10月,Danny Cohen的文章<论圣战以及对和平的祈祷>(On holy wars and a plea for peace)将这一对词语引入了计算机界(<程序设计实践>第9章).这么看来,所谓大端和小端,也就是big-endia

JAVA变量在内存中的分配

变量是程序中最基本的存储单元,从本质上讲,变量其实是内存中的一小块区域.所以要为其分配一定的存储空间. 变量的类型 按数据类型: 基本数据类型 引用数据类型 按声明的位置: 局部变量 成员变量 程序在计算机内存的分布: 栈区: 由编译器自动分配释放,主要存放Java程序运行时所需的局部变量.方法的参数.对象的引用以及中间运算结果等数据.其操作方式类似于数据结构的栈. 堆区: 不是系统为程序自动分配的,是程序执行过程中有new语句为变量分配的,主要存放Java程序运行时创建的所有引用类型,即使指向

java中静态变量在内存中的位置

java程序在内存中的存储分配情况: 一.堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令) 2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身 栈区: 1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中 2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问. 3.栈分为3个部分:基本类型变量区.执行环境上下文.操作指令区(存

各种变量在内存中的高地址低地址

先确认一下这里"低地址高地址"的定义,这里并不是指的大端小端中的地址高低,而是内存中的地址 1.全局变量 先定义的全局变量位于低地址,后定义的位于高地址. 2.栈中变量 (栈中变量指的是由编译器自动分配释放的变量) 由于栈是往低地址生长的,所以先声明的变量位于高地址. 3.堆中变量 (堆中变量指的是由程序员分配释放的变量,例如new,malloc) 结论:由于堆是往高地址生长的,所以先声明的变量位于低地址. 原文地址:https://www.cnblogs.com/pjl1119/p/