四大内存区域

C++在程序运行时,将内存大方向划为4个区域

  1. 代码区 存放函数体的二进制代码,由操作系统进行管理
  2. 全局区 存放全局变量和静态变量和常量
  3. 栈区 由编译器自动分配释放,存放函数的参数值,局部变量等
  4. 堆区 由程序员分配和释放,程序结束时由操作系统回收

代码区

存放的是二进制代码在程序运行前
未执行前分为两个区域
代码区:
存放CPU执行的机器指令
代码区是共享的,目的是对于频繁执行的程序,只需要在内存中有一份代码即可。
代码区是只读的,目的是防止被篡改
全局区
全局变量和静态变量存放在此
该区域的数据在程序后由操作系统释放。
局部常量不存放在全局区中

全局区

全局变量,常量会放在全局区中。

栈区

栈区的数据由编译器管理开辟和释放。
需要注意的是,局部变量将会存放在栈区,栈区的数据在函数运行结束后会被释放。
所以不要返回局部变量的地址。形式参数也是局部变量,也会存放在栈区。

堆区

程序员管理的数据。
在堆区使用new开辟数据。

  1. #include<iostream>
  2. int main(){
  3. int *p;
  4. p = new int(10);
  5. //*p == 10
  6. }

使用new则会返回一个存放的地址,这个数据在堆区。
提示,new的本质是开辟内存空间,可以在链表开辟空间中看到类似思想。
new在堆区开辟一个空间,值是变量值,而返回值为堆区地址。
new或delete的底层实现都是malloc或是free
有以下实例:

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int* p;
  5. p = new int(20);
  6. cout << *p << endl;
  7. //Console will print 20
  8. delete p;
  9. //now *p is a wild pointer.
  10. return 0;
  11. }

而我们在标准的一个动态链表中可以看到类似的思想:

  1. #include <iostream>
  2. using namespace std;
  3. struct LinkedNode {
  4. int data;
  5. LinkedNode* next;
  6. };
  7. typedef LinkedNode Node;
  8. Node* createNode(int i_data){
  9. Node* p;
  10. p = (Node*)malloc(sizeof(Node));
  11. if (p != NULL) {
  12. p->data = i_data;
  13. }
  14. else {
  15. cout << "allocote failed!";
  16. }
  17. return p;
  18. }
  19. int main() {
  20. Node* p1;
  21. int* p2;
  22. p1 = createNode(10);
  23. p2 = new int(10);
  24. cout << p1->data << endl << *p2 << endl;
  25. free(p1);
  26. delete p2;
  27. return 0;
  28. }

两种方法实质上是一样的。