1、C&C++内存分布
如上代码中各变量的存储区域。
1. 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口 创建共享共享内存,做进程间通信。
3. 堆用于程序运行时动态内存分配,堆是可以上增长的。
4. 数据段--存储全局数据和静态数据。
5. 代码段--可执行的代码/只读常量。常量区是被保护的,不能被修改。
那么为什么要分这些区域?------方便管理。
哪个是我们要重点关注的?-------堆。留给程序员自己控制的。
我们先来看下面的一段代码和相关问题:
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在哪里?__C__ staticGlobalVar在哪里?__C__
staticVar在哪里?__C__ localVar在哪里?__A__
num1 在哪里?__A__
char2在哪里?__A__ *char2在哪里?__A__
pChar3在哪里?__A__ *pChar3在哪里?__D__
ptr1在哪里?__A__ *ptr1在哪里?__B__
2. 填空题:
sizeof(num1) = __40__;
sizeof(char2) = __5__; strlen(char2) = __4__;
sizeof(pChar3) = __4或8__; strlen(pChar3) = __4__;
sizeof(ptr1) = __4或8__;
3. sizeof 和 strlen 区别?
sizeof是运算符,编译时,内置类型根据类型大小定义计算大小,自定义类型根据内存对齐规则计算大小
strlen是字符串函数,运行时,编译器去call函数的地址,然后push,move等等,来实现strlen
char2:在常量区有一个[abcd\0],然后在栈上开辟一个空间数组,然后拷贝过去。和num1是类似的。在语法上都代表整个数组。在栈上。
*char2:这里即将首元素的地址解引用,即*char2 == a,也在栈上。
pChar3:以const修饰的不一定代表是在常量区,pChar3是一个指针,是在栈上,它指向的是在常量区的[abcd\0]。在栈上。
*pChar3:就是[abcd\0]这个字符串的首元素a,在常量区。
ptr1:代表我们开了一个空间,ptr1这个指针代表指向这个空间的首元素,在栈上。
*ptr1:就是malloc开的空间,在堆上。
sizeof(num1):代表整个数组的大小。
sizeof(char2):代表整个数组的大小。有\0。
sizeof(pChar3):代表pChar3这个指针的大小。
strlen(char2)和strlen(pChar3):都是这个[abcd\0]的长度。
2、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);
}
calloc和malloc的区别:calloc开辟空间后会初始化为0,malloc不会。
不需要free(p2),因为realloc