四大内存区域
C++在程序运行时,将内存大方向划为4个区域
- 代码区 存放函数体的二进制代码,由操作系统进行管理
- 全局区 存放全局变量和静态变量和常量
- 栈区 由编译器自动分配释放,存放函数的参数值,局部变量等
- 堆区 由程序员分配和释放,程序结束时由操作系统回收
代码区
存放的是二进制代码在程序运行前
未执行前分为两个区域
代码区:
存放CPU执行的机器指令
代码区是共享的,目的是对于频繁执行的程序,只需要在内存中有一份代码即可。
代码区是只读的,目的是防止被篡改
全局区
全局变量和静态变量存放在此
该区域的数据在程序后由操作系统释放。
局部常量不存放在全局区中
全局区
栈区
栈区的数据由编译器管理开辟和释放。
需要注意的是,局部变量将会存放在栈区,栈区的数据在函数运行结束后会被释放。
所以不要返回局部变量的地址。形式参数也是局部变量,也会存放在栈区。
堆区
程序员管理的数据。
在堆区使用new开辟数据。
#include<iostream>
int main(){
int *p;
p = new int(10);
//*p == 10
}
使用new则会返回一个存放的地址,这个数据在堆区。
提示,new的本质是开辟内存空间,可以在链表开辟空间中看到类似思想。
new在堆区开辟一个空间,值是变量值,而返回值为堆区地址。
new或delete的底层实现都是malloc或是free
有以下实例:
#include <iostream>
using namespace std;
int main() {
int* p;
p = new int(20);
cout << *p << endl;
//Console will print 20
delete p;
//now *p is a wild pointer.
return 0;
}
而我们在标准的一个动态链表中可以看到类似的思想:
#include <iostream>
using namespace std;
struct LinkedNode {
int data;
LinkedNode* next;
};
typedef LinkedNode Node;
Node* createNode(int i_data){
Node* p;
p = (Node*)malloc(sizeof(Node));
if (p != NULL) {
p->data = i_data;
}
else {
cout << "allocote failed!";
}
return p;
}
int main() {
Node* p1;
int* p2;
p1 = createNode(10);
p2 = new int(10);
cout << p1->data << endl << *p2 << endl;
free(p1);
delete p2;
return 0;
}
两种方法实质上是一样的。