◎回顾内存区:C语言C++的内存区是一样的。
共五个区:栈区,堆区,全局区,代码区,文字常量区
把握内存的开辟时间和销毁时间,就能掌握这五个区的要点
编辑 ==》 编译 ==》 连接 ==》 运行
敲代码 语法检查 库文件
#栈区statck
运行到时开辟,所在函数结束(即作用域结束)时销毁
如:
void foo(int arg)
{
int LocalVar;
if (100 == arg )
{
int var;
}
}
实际上代码为
void foo(auto int arg)
{
auto int LocalVar;
if (100 == arg )
{
auto int var;
}
}
因为auto一般都是不用写的。只有形式参数和局部变量可以定义为auto变量。全局变量之前不能加auto,编译器也不会自动给全局变量加auto。
arg,LocalVal,var都在栈区,局部变量
内存不由程序员回收,由编译器自动回收。
#堆区heap
调用malloc和calloc时开辟,free()时销毁,堆区的内存必须手动回收。
int main()
{
int* p = (int*)malloc;//p在栈区,但是p所指向的内存是堆区
free(p);
return 0;
}
C++中用new和delete。
#全局区
编译时(main函数执行之前)开辟,并自动初始化。main()函数结束时销毁。在函数内部定义时,在变量类型前加static关键字。
int foo()
{
static int var;
var++;
}
int main()
{
foo();
foo();
return 0;
}
foo()函数执行时不会执行static int var;这条语句。因为它是在编译时执行的。
全局变量无论前面是否加static都是在全局区的。
全局变量之前加static变量和不加static变量有什么区别?通过使用编译器写测试代码查看区别:
作用域不同,加了static后,全局变量的作用域限定在本文件内部,不允许使用extern关键字扩展到其他文件内部。但是没加static的全局变量可以被扩展到其他文件。
extern只能用于扩展非静态的全局变量。
#代码区
函数本身是在代码区。
void foo(void)
{
}
int main(void)
{
void (*pFn)() = foo;//foo是地址常量
foo();
pFn();
printf("%x\n",foo);
return 0;
}
#文字常量区
字面值在文字常量区。
int foo()
{
printf("%d",100);
}
int foo()
{
printf("%d",100);//100在文字常量区
char arr[] = "boy";//boy在栈区
char*p = "girl";//girl在文字常量区
//*p = 'h';//错误,文字常量区不能改写内容,运行时才报错“该内存不能写”
arr[0] = 'm';//可以修改,因为在栈区
*arr = 'k';
}
总结:栈的大小小的多;堆区的内存多的多,而且可以使用虚拟内存,会调用硬盘存储。除了文字常量区的内存不能写之外,其他内存区都可以写。