c语言内存四区、数据存储范围和内存存储方向
(1)代码区通常是共享只读(代码无法修改)的,即可以被其他的程序调用,例如运行两个qq,除了数据不一样,代码都是一样的,
每次运行qq,都会将代码和数据加载到内存中,除了数据,每次加载的代码都是一样的,可以大大节省内存。
(2)栈是由系统分配内存,栈的内存是固定的。
(3)堆区是程序员自己分配内存和释放内存,如果不释放内存,那么就只能等程序结束后才会由系统回收。内存不释放,那么在程序运行期间可能会导致内存不够用。
程序在没有运行前只有代码区和数据区,运行程序后会加载到内存中,才有堆区和栈区。
数据存储范围?
1.栈区:栈区内存自动申请,不需要程序手动管理(我们说的分配内存其实是分配一个地址,内存其实是运行之后才会分配)
#include<stdio.h> int* myFunc() { int a = 10;//局部变量放在栈区,使用完后内存自动释放,所以不要返回局部变量的地址 return &a;//数组名就是数组的首地址 } char* getString() { char str[] = "Hello World"; return str; } void test01() { int* p = myFunc();//myFunc中的a内存使用完后即被释放了,不会在test01中出现,所以打印不出值,会报错 printf("*p=%d\n",*p); } void test02() { char* s = NULL; s=getString(); printf("s=%s\n",s); } int main() { test01(); test02(); }
第一步:当执行getString方法中的代码时候
第二步:getString方法执行完后,栈区中的数组str的内存就释放了,所以此时0x002这个地址就不存在了,当然就找不到值 hello World了。
输出结果
*p=10 s=烫烫烫烫烫烫狞? 请按任意键继续. . .
2.堆区:开辟堆空间 int * p= malloc(sizeof(int)*10);
#include<stdio.h> #include<string.h> #include<stdlib.h> void alloctateSpace(char * p) { p = malloc(100);//分配100个字节的内存 memset(p,0,100);//将这块内存中的值初始化为0值 strcpy(p,"hello world!"); } void test02() { char* ret = NULL; alloctateSpace(ret); printf("ret=%s\n",ret);//ret=null } int main() { test02(); system("pause"); }
首先,执行allocateSpace方法完后,由于char * p是形参,所以执行完该方法后,p就被释放掉了
所以最终ret的地址为NULL。
4556