C语言程序运行时数据在内存的分布

C程序运行,操作系统为其分配一块内存空间(进程),而这一块内存空间可分为几个段: C语言程序运行时数据在内存的分布_第1张图片
1.代码段(text),也称文本段(Text Segment),存放着程序的机器码和只读数据,可执行指令就是从这里取得的。代码段处于内存的低地址段,这个段在内存中一般被标记为只读,任何对该区的写操作都会导致段错误(Segmentation Fault)。

#include 
#include 
int main(){
	char *p = "can not change.";//指针变量p的地址在栈上;“can not change”是字符串常量是只能读数据,存放在代码段;指针p指向代码段中字符串常量“can not change”。
	char *a = "add character";
	strncat(p,a,strlen(a));//将指针a指向的strlen(a)个字符连接到指针p指向的字符串结尾;
	printf("%s\n",p);
	return 0;
}

编译不会发生错误,但结果显示段错误(linux)或者提示该内存不能为"written";

#include 
void test();
void test(){//函数存放在代码段,占用代码段的空间;
	printf("low address");
}
int main(){
	printf("%ld\n",test);//输出地址为低地址段内存;
	printf("%ld\n","cdf");//输出地址为低地址段内存;
	return 0;
}

2.数据段,包括已初始化的数据段(data)和未初始化的数据段(bss:Block Started by Symbol),前者用来存放保存全局的和静态的已初始化变量,后者用来保存全局的和静态的未初始化变量。数据段在编译时分配。

#include 
#define LIN 34 //不占用内存,只是告诉编译器把LIN换成34;
entern int a;//仅是声明了一个外部变量a,不占用内存,a是在其他文件中完成定义;
int b;//未初始化的全局变量b,	存放在bss内;
int i = 3;//初始化的全局变量i,存放在初始化数据段内;
static char p;//未初始化的全局静态变量p,	存放bss内,其作用域为整个文件内(外部文件不能用entern引用该变量);
int main(){
	static char e;//未初始化的局部静态变量p,	存放bss内;
	return 0;
}
  1. (Heap):用来存储程序运行时手动分配(malloc、realloc、calloc)的变量,内存分配由低到高。

    #include 
    #include 
    int main(){
    	char *p;//声明一个字符型指针p,由系统自动存放在栈上;
    	p = (char *)malloc(34);//在堆中划分一块34byte的内存空间,并用指针p指该内存块的首地址;
    	printf("%ld\n",&p);//指针p在栈上的地址;
    	printf("%ld\n",p);//在指针p内存放的在堆中分配的内存块首地址;
    	free(p);//释放堆上的内存空间;
    	p = NULL;//指针指向0;
    	return 0;
    }
    

堆中的内存分配由低到高:

	#include 
	#include 
	int main(){
		char *a;
		int i;
		for(i = 0;i < 4; ++i){
			a = (char *)malloc(5);
			printf("分配的第%d个地址:%ld\n",i,a);
		}
		free(a);//释放内存
		a = NULL;//指针指向0
		return 0;
	}

输出的结果为由高到低的堆区地址;
4.(Stack)是一种用来存储函数调用时的临时信息的结构,如函数调用所传递的参数、函数的返回地址、函数的局部变量等。 在程序运行时由编译器在需要的时候分配,在不需要的时候自动清除。

#include 
void first(int i){
	int b;//存放在栈上
	printf("i在栈上的地址:%d\n",&i);
	printf("%ld\n",&b);//变量b比变量i先分配内存;
}
int main(){
	int a = 2;//存放在栈上;
	printf("a在栈上的地址:%ld\n",&a);
	first(a);//只有在函数调用时,系统才为函数的形参分配空间
	return 0;
}

数组和结构体的存放:

#include 
int c[12];//存放在数据段
struct test{
	int a;
	int b;
}s;//定义一个结构体变量s,存放在数据段,未初始化的全局变量;
int main(){
	int e[12];//系统为数组在栈上分配12字节的空间,数组名存放该空间的首地址;
	struct test p;//声明一个结构体变量p,其存放在栈上;
	s.a = 3;//存放在数据段;
	p.a = 3;//存放在栈上;
	return 0;
}

你可能感兴趣的:(C语言)