内存分区
四大分区
- 代码区:二进制代码,操作系统管理
- 全局区:全局变量、静态变量、常量
- 栈区:编译器自动分配释放,函数的参数值,局部变量等
- 堆区:手动分配释放,程序结束时未释放的将由操作系统回收
不同的区赋予了不同数据不同的生命周期,实现灵活编程
编译后运行前
程序编译后生成exe、bat、out等可执行文件,在运行程序前,内存分为两部分:
- 代码区:存放待执行的机器指令,其为共享只读
- 全局区:全局变量、静态变量、const修饰的全局常量、字符串常量。该区域数据由程序结束后操作系统释放
ps:函数体内的变量都是局部变量
程序运行后
栈区
存放函数的参数值和局部变量等,由编译器自动分配释放
ps:不要返回局部变量地址,因为其由编译器自动释放
int* function(int b) {
int a = 1;
return &a;
}
int main() {
int c = 3;
int* p = function(c);
cout << *p << endl;
cout << *p << endl;
}
int* function(int b) {
int a = 1;
return &b;
}
int main() {
int c = 3;
int* p = function(c);
cout << *p << endl;
cout << *p << endl;
}
··可以看出上面两个例子的区别,分别是函数function的局部变量和形参,编译器自动分配和释放,对于形参b函数执行结束立刻就回收释放,对于局部变量a进行了一次保留,因此尽量不要返回局部变量的地址。
堆区
程序员手动分配和释放,若不释放,则程序运行结束时由操作系统回收,常用**new**开辟
<br>
1 new使用
new 数据类型()
返回该类型的指针
int* function(){
int* p = new int(10);
return p;
}
int main(){
int* p1 = function();
cout<<*p1<<endl;
cout<<*p1<<endl;
}
-------------------------------
10
10
可以看出上述的function函数内部用new在堆区开辟了空间,其由程序员手动控制释放,因此p指针在程序结束后保留一次将地址的值返回给p1,p1指向了堆区的数据,p由编译器回收后,p1仍然指向堆区,因此一直会是10的输出
2 释放空间
delete释放空间
delete p;
cout<<*p<<endl;
报错:
p已经释放,再次解引用*p会报错
3 new 数组
int* arr = new int[10] //10是是个数组,返回首地址
for (int i = 0;i<10;i++){
arr[i] = i+100;
} //赋值100到109
// 释放数组
delete[] arr; //加上[]表示数组