代码区 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 是一种先进后出的内存结构, 所有的自动变量, 函数的形参都是由编译器自动放出栈中, 当一个自动变量超出其作用域时, 自动从栈中弹出.
- #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 分配内存了.
内存四区
来源: http://www.bubuko.com/infodetail-3101944.html