内存四区
Posted wanghao-boke
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存四区相关的知识,希望对你有一定的参考价值。
1.代码区:
代码区Code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的。
2. 静态区
所有的全局变量以及程序中的静态变量都存储在静态区。
#include<stdio> int c = 0;//静态区 void test(int a,int b) printf(“%d %d\n”,&a,&b); //在栈区 int main() static int d = 0; int a = 0; //栈区 int b = 0; printf(“%d %d %d %d %d\n”,&a,&b,&c,main,d); return 0;
3.堆区
对于一个32位操作系统,最大管理4G内存,其中1G是给操作系统自己用的,剩下的3G都是给用户程序,一个用户程序理论上可以使用3G空间
int *p = (int*)malloc(sizeof(int) * 10); //在堆中申请内存,在堆中申请了一个10个int型大小内存。 char *p1 = malloc(sizeof(char) * 10); //在队中申请10个char这么大的空间 free(p);//释放通过malloc分配的堆内存 free(p1); //释放通过maclloc分配的对内存
4.栈区
栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出。
对于自动变量,什么时候入栈,什么时候出栈,是不需要程序控制的,由C语言编译器实现的。
#include<stdio.h> int *geta() //函数的返回值是个指针 auto int a = 100; return &a; //int a的作用域就是 int main() int *p = geta();//这里得到的是一个临时变量的地址,这个地址在函数geta调用结束以后已经无效了 *p = 100; printf(“%d\n”,*p); return 0;
栈不会很大,一般都是K为单位
栈溢出:当栈空间已满,但还往栈内存压变量,这个就叫栈溢出。
int *geta() //错误,不能将一个栈变量的地址通过函数的返回值返回 int a = 0; return &a; int *geta1() //通过函数的返回值可以返回一个对地址,但记得一定要free int *p = malloc(sizeof(int)); return p; int main() int *getp = geta1(); *getp = 100; free(getp);
int *geta2() //合法 static int a = 100; return &a; int main() int *getp = geta2(); *getp = 100; //free(getp);
int main() //结果正常。 int *p = NULL; p = malloc(sizeof(int) * 10); p[0] = 1; p[1] = 2; printf(“p[0] = %d, p[1] = %d\n”,p[0],p[1]); // free(p);
//结果崩溃 void getheap(int *p) p = malloc(sizeof(int) * 10); int main() int *p = NULL; getheap(p); p[0] = 1; p[1] = 2; printf(“p[0] = %d, p[1] = %d\n”,p[0],p[1]); // free(p);
分析:主函数的p的值NULL ,传递给函数getheap中的*p,在函数中malloc分配的内存分配给了函数中的*p,分配的malloc是堆中的,mian中的内存都在栈中的,意味这main函数中的p没有得到内存地址。
修正:
void getheap(int **p) *p = (int*)malloc(sizeof(int) * 10); int main() int *p = NULL; getheap(&p); p[0] = 1; p[1] = 2; printf(“p[0] = %d, p[1] = %d\n”,p[0],p[1]); // free(p);
这样就可以给指针p分配内存了。
以上是关于内存四区的主要内容,如果未能解决你的问题,请参考以下文章