一、C/C++内存分布
我们先来看下面的一段代码和相关问题
int globalVar = 1; static int staticGlobalVar = 1; void Test() { static int staticVar = 1; int localVar = 1; int num1[10] = { 1, 2, 3, 4 }; char char2[] = "abcd"; const char* pChar3 = "abcd"; int* ptr1 = (int*)malloc(sizeof(int) * 4); int* ptr2 = (int*)calloc(4, sizeof(int)); int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4); free(ptr1); free(ptr3); }
1、选择题
选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
globalVar在哪里?____ staticGlobalVar在哪里?____
staticVar在哪里?____ localVar在哪里?____
num1 在哪里?____
C C C A A
char2在哪里?____ *char2在哪里?___
pChar3在哪里?____ *pChar3在哪里?____
ptr1在哪里?____ *ptr1在哪里?____
A A A C A B
2、填空题
sizeof(num1) = ____;
sizeof(char2) = ____; strlen(char2) = ____;
sizeof(pChar3) = ____; strlen(pChar3) = ____;
sizeof(ptr1) = ____;
40 5 4 4/8 4 4/8
3、sizeof 和 strlen 区别?
sizeof是运算符计算的是内存的大小,包括’\0’,strlen计算的是字符串的大小,不计算’\0’。
4、总结
- 栈区主要存在局部变量和函数参数,其空间的管理由编译器自动完成,无需手动控制,堆区是自己申请的空间,在不需 要时需要手动释放。
- 对于栈来讲,生长方向是向下的,也就是向着内存地址减小的方向;对于堆来讲,它的生长方向是向上的,是向着内存地址增加的方向增长。
- 对于堆来讲,频繁的 new/delete 势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题。
- 32位系统下,最大的访问内存空间为4G,所以不可能把所有的内存空间当做堆内存使用。
- 栈可以静态分配,堆不可以。
- 栈和堆都可以动态分配。
- 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。
- 数据段–存储全局数据和静态数据。
- 代码段–可执行的代码/只读常量。
二、 C语言中动态内存管理:malloc/calloc/realloc/free
void Test () { int* p1 = (int*) malloc(sizeof(int)); free(p1); // 1.malloc/calloc/realloc的区别是什么? int* p2 = (int*)calloc(4, sizeof (int)); int* p3 = (int*)realloc(p2, sizeof(int)*10); // 这里需要free(p2)吗? free(p3 ); }
1、 malloc/calloc/realloc的区别?
相同点
1.都是从堆上申请空间;
2.都需要对返回值判空;
3.都需要用户free释放;
4.返回值类型相同(都是void*);
5.都需要类型转化;
6.底层实现是一样的,都需要开辟多余的空间,用来维护申请的空间。
不相同
1.函数名字不同,参数类型不同;
2.calloc函数会对申请空间初始化,并且初始化为0;
3.malloc函数申请空间必须使用memset进行初始化;
4.realloc函数是对已经存在的空间进行调整,当第一个参数传入NULL的时候和malloc函数一样,其调整分为两种请况:
A.调整的空间比原有空间大
a.大了一点:多出来的空间小于下面空闲的空间 调整方法: (1)直接延伸申请空间; (2)返回空间首地址。 b.打了很多:多出来空间大于下面空闲空间 调整方法: (1)重新开辟新空间; (2)将旧空间的内容拷贝到新空间中; (3)释放旧空间; (4)返回新空间的首地址。
B.调整的空间比原有空间小
调整方法: (1)将原有空间缩小; (2)返回旧空间首地址。
2、 malloc的实现原理?
三、 C++内存管理方式
C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
1、 new/delete操作内置类型
1、演示1
2、演示2
3、演示3
注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[],注意:匹配起来使用。