【C++初阶】C++内存管理(上)

简介: 【C++初阶】C++内存管理

一.C/C++内存分布图

作为C/C++方向的从业者,必须关注的四块空间:

  1. 栈(局部数据)
  2. 堆(动态申请数据)
  3. 数据段(全局数据和静态数据)
  4. 代码段(可执行代码和可读常量)

c183bbac2152220438970e5685e90bab.png

int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
  static int staticVar = 1;
  int localVar = 1;
  int num1[10] = { 1, 2, 3, 4 };
  char char2[] = "abcd";
  const char* pChar3 = "abcd";
  int* ptr1 = (int*)malloc(sizeof(int) * 4);
  int* ptr2 = (int*)calloc(4, sizeof(int));
  int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
  free(ptr1);
  free(ptr3);
}

a829d7858e89cc9dcce914643b57e82e.png

解析:


globalVar定义在所有的函数外,所以是全局变量,位于数据区


staticGlobalVar定义在函数体外[全局],且被static修饰[静态],所以是静态(全局)变量,位于数据区


staticVar定义在函数体外[局部],且被static修饰[静态],所以是静态(局部)变量,位于数据区


localVar定义在函数体内[局部],所以是局部变量,位于栈区


num1是整型数组名,定义在函数体内[局部],所以是局部变量,位于栈区


char2是字符数组名,定义在函数体内[局部],所以是局部变量,位于栈区


*char2是字符数组存放的内容,位于栈区


pChar3是一个指针,指向代码段中常量字符串“abcd”,定义在函数体内[局部],位于栈区


*pChar3是常量字符串“abcd”,位于代码段


ptr1指向动态申请的空间,定义在函数体内[局部],位于栈区


*ptr1是动态申请的空间里的内容,位于堆区


关于第7题和第9题区别:

b169b0cc6704dab52de183b4cb50da04.png

二.new和delete内存管理

C 语言中的malloc是函数,C++中的new是关键字,操作符,都是在堆上动态申请的空间

下面我针对内置类型和自定义类型比较new,delete和malloc,free


1.对于内置类型

C 语言和C++默认都没有对各自动态申请的内存进行初始化

97cbc592808026f88884072c028727f4.png

int main()
{
  //C语言
  int* p1 = (int*)malloc(40);
  free(p1);
  //C++,默认不初始化
  int* ptr1 = new int;
  delete ptr1;
  //指定初始化
  int* ptr2 = new int(100);
  //ptr2 = nullptr;如果后面不使用了,可以置空
  delete ptr2;
  //动态申请数组
  //不初始化
  int* ptr3 = new int[10];
  delete[] ptr3;
  //完全初始化
  int* ptr4 = new int[10]{ 1,2,3,4,5,6,7,8,9,10 };
  delete[] ptr4;
  //不完全初始化
  int* ptr5 = new int[10]{ 1,2,3,4,5 };
  delete[] ptr5;
  return 0;
}

3a2fafa925f2b0d0743f1e29884d17c0.png

对于内置类型:

new/delete相比与malloc/free,只是用法上的区别

2.对于自定义类型(重点)

new/delete主要是针对自定义类型设计的,对于自定义类型,

new除了在堆上开辟空间,还会自动调用构造函数,完成对象的初始化

delete除了在堆上释放空间,还会自动调用析构函数,完成对象的资源清理

class A
{
public:
  A(int a = 10)
    :_a(a)
  {
    cout << "构造函数" << endl;
  }
  ~A()
  {
    cout << "析构函数" << endl;
  }
private:
  int _a;
};
int main()
{
  A* ptr1 = new A;
  delete ptr1;
  cout << "____________________________________" << endl << endl;
  A* ptr2 = new A[4];
  delete[] ptr2;
  return 0;
}

2125e6025e1361ca5d9e16d95cae5e8a.png

案例:对于我们之前学过的单链表那块

C语言:

ListNode* BuyListNode(int val)
{
  ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
  newnode->_val = val;
  newnode->_next = nullptr;
}
int main()
{
    ListNode* n1 = BuyListNode(1);
  ListNode* n2 = BuyListNode(2);
  ListNode* n3 = BuyListNode(3);
  n1->_next = n2;
  n2->_next = n3;
    return 0;
}

C++:

struct ListNode
{
  int _val;
  ListNode* _next;
  ListNode(int val = 0)
    :_val(val)
    ,_next(nullptr)
  {}
};
int main()
{
  //创建链表
  ListNode* n1 = new ListNode(1);
  ListNode* n2 = new ListNode(2);
  ListNode* n3 = new ListNode(3);
  ListNode* n4 = new ListNode(4);
  ListNode* n5 = new ListNode(5);
  n1->_next = n2;
  n2->_next = n3;
  n3->_next = n4;
  n4->_next = n5;
  return 0;
}

d3c2af59895da30bd71cfd0ad2c376cd.png


目录
相关文章
|
12天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
36 4
|
1月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
108 21
|
1月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
1月前
|
存储 C语言 C++
【C++打怪之路Lv6】-- 内存管理
【C++打怪之路Lv6】-- 内存管理
38 0
【C++打怪之路Lv6】-- 内存管理
|
1月前
|
存储 C语言 C++
【C/C++内存管理】——我与C++的不解之缘(六)
【C/C++内存管理】——我与C++的不解之缘(六)
|
1月前
|
程序员 C语言 C++
C++入门5——C/C++动态内存管理(new与delete)
C++入门5——C/C++动态内存管理(new与delete)
68 1
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
176 1
|
1月前
|
C++
C/C++内存管理(下)
C/C++内存管理(下)
49 0
|
1月前
|
存储 Linux C语言
C/C++内存管理(上)
C/C++内存管理(上)
38 0
|
1月前
|
Linux C++
Linux c/c++文件虚拟内存映射
这篇文章介绍了在Linux环境下,如何使用虚拟内存映射技术来提高文件读写的速度,并通过C/C++代码示例展示了文件映射的整个流程。
48 0