内存五区
堆区(heap)
malloc,new,free,delete,需要手动释放内存
一般由程序员分配释放,若不手动释放,程序结束时可能由操作系统回收。
栈区(stack)
程序局部变量
由编译器自动分配释放,存放函数的参数值,局部变量的值等。
全局区(static)
常量和全局变量
全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量在一块区域,未初始化的在相邻的另一块区域,该区域在程序结束后由操作系统释放。
常量区
字符串常量和其他常量的存储位置,程序结束后由操作系统释放。
代码区
存放函数体的二进制代码
调用流程:
- 操作系统把物理硬盘代码load到内存
- 操作系统把C代码分成四个区
全局区分析
静态局部变量在调用函数后就保存在全局区。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int* p = getA();
printf("p = %d, *p = %d", p, *p);//p = 19111936, *p = 10
printf("\n");
return 0;
}
指针指向谁,就把谁的地址赋值给指针。
当两个函数的不同指针的内容(常量)相同时,在内存的全局区只占用一块相同的空间。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* getStr1() {
char* p = "abcdef";//文字常量区
return p;
}
char* getStr2() {
char* q = "abcdef";//文字常量区
return q;
}
int main()
{
char* p = NULL;
char* q = NULL;
p = getStr1();
printf("p = %s, p = %d\n", p, p);
q = getStr2();
printf("q = %s, q = %d\n", q, q);
return 0;
}
栈区分析(由高到低生长)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* getStr()
{
char str[] = "adsafwqd";//保存在栈区
printf("str = %s\n", str);
return str;
}
int main(void)
{
char* p = NULL;
p = getStr();//getStr()运行完毕,str空间自动回收,str空间内容未知,导致乱码
printf("p = %s\n", p);
printf("\n");
return 0;
}
堆区分析(由低到高生长)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* getStr()
{
char str[] = "adsafwqd";//保存在栈区
printf("str = %s\n", str);
return str;
}
char* getStr2() {
char* tmp = (char*)malloc(100);//堆区
if (tmp == NULL) {
return NULL;
}
strcpy(tmp, "sadasfwd");
return tmp;
}
int main(void)
{
char* p = NULL;
char* q = NULL;
//p = getStr();//getStr()运行完毕,str空间自动回收,str空间内容未知,导致乱码
//printf("p = %s\n", p);
q = getStr2();
if (q != NULL) {
printf("q = %s\n", q);
free(q);//释放空间
q = NULL;//指空
}
printf("\n");
return 0;
}
内存存放方向也是从低到高。