1.1程序运行之前
在程序编译后,生成.exe可执行程序,未执行该程序前分为两个区域
(1)代码区:
存放CPU执行的机器指令(就是我们所写的所有代码的二进制形式)
特点:a.代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。
b.代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令。
(2)全局区:
全局变量和静态变量存放在此
全局区还包含了常量区,字符常量和其他常量也存放在此。该区域的数据在程序结束后由操作系统释放。
//创建全局变量,在main函数外面就是全局变量
int b = 10;
//const修饰的全局变量
const int g = 10;
int main() {
//全局区:全局变量、静态变量、常量(const修饰的局部变量不是)
//区分是否在全局区很简单,只需要输出地址是否在同一区域
//创建局部变量
int a = 10;
//创建静态变量,在普通变量前面加static,属于静态变量
static int c = 10;
//常量:字符常量、const修饰的全局变量、const修饰的局部变量
string m = "hello";
const int h = 10;
system("pause");
return 0;
}
2.程序运行之后
栈区:
由编译器自动分配释放,存放函数的参数值,局部变量等。
注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放。
//栈区:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放
int* function(int b) //形参存放在栈区
{
//局部变量存放在栈区,栈区的数据在执行完成后自动释放
int a = 10;
//int b = 20;
//返回局部变量的地址
return &a;
}
int main() {
//调用函数获取局部变量的地址
int * p = function(20);
//输出地址:第一次可以正常打印,是因为编译器做了保留
cout << *p << endl;
//第二次就无法正常打印了,会出现乱码
cout << *p << endl;
system("pause");
return 0;
}
2.2堆区
由程序员分配释放,若程序员不释放,程序运行结束时由操作系统回收。
在c++中主要利用new在堆区开辟内存。
//堆区:
int * func()
{
//利用new关键字可以将数据开辟到堆区
//指针本质上也是局部变量,放在栈上,指针保存的数据是存放在堆区
int * p = new int(10);
return p;
}
int main() {
//在堆区开辟数据
int * p = func();
cout << *p << endl;
cout << *p << endl;
system("pause");
return 0;
}
2.3 new操作符
c++中利用new操作符在堆区开辟数据
堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符delete
语法:new 数据类型
注意:利用new创建的数据,会返回该数据对应的类型的指针.
//堆区:
int * func()
{
//利用new关键字可以将数据开辟到堆区
//指针本质上也是局部变量,放在栈上,指针保存的数据是存放在堆区
int * p = new int(10);
return p;
}
//在堆区创建数组
void func2() {
//在堆区利用new开辟数组,返回的是数组的首地址
int * arr = new int[10];
//对数组进行赋值
for (int i = 0; i < 10; i++)
{
arr[i] = 10 + i;
cout << arr[i] << endl;
}
//释放堆区数组,[]表明释放的是数组
delete[] arr;
}
int main() {
//在堆区开辟数据
int * p = func();
cout << *p << endl;
cout << *p << endl;
//释放堆区变量
delete p;
//cout << *p << endl; //没有权限访问,因为该地址已经被释放
//调用数组函数
func2();
system("pause");
return 0;
}