【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天前
|
存储 C语言 C++
【C/C++】动态内存管理( C++:new,delete)
C++的`new`和`delete`用于动态内存管理,分配和释放内存。`new`分配内存并调用构造函数,`delete`释放内存并调用析构函数。`new[]`和`delete[]`分别用于数组分配和释放。不正确匹配可能导致内存泄漏。内置类型分配时不初始化,自定义类型则调用构造/析构。`operator new`和`operator delete`是系统底层的内存管理函数,封装了`malloc`和`free`。定位`new`允许在已分配内存上构造对象,常用于内存池。智能指针等现代C++特性能进一步帮助管理内存。
|
12天前
|
存储 编译器 程序员
【C/C++】动态内存管理(C:malloc,realloc,calloc,free)
探索C++与C语言的动态内存管理:从malloc到new/delete,了解内存分布及栈、堆的区别。文章涵盖malloc、realloc、calloc与free在C中的使用,强调内存泄漏的风险。C++引入new和delete,支持对象构造与析构,还包括operator new和placement-new。深入分析内存管理机制,揭示C与C++在内存处理上的异同。别忘了,正确释放内存至关重要!
|
13天前
|
算法 Java C++
C++和Python在内存管理上的主要区别是什么?
【7月更文挑战第2天】C++和Python在内存管理上的主要区别是什么?
12 1
|
5天前
|
安全 算法 编译器
C++一分钟之-内存模型与数据竞争
【7月更文挑战第10天】了解C++11内存模型对多线程编程至关重要。它定义了线程间同步规则,包括顺序一致性、原子操作和内存屏障。数据竞争可能导致不确定行为,如脏读和丢失更新。可通过互斥量、原子操作和无锁编程避免竞争。示例展示了`std::mutex`和`std::atomic`的使用。掌握内存模型规则,有效防止数据竞争,确保多线程安全和性能。
11 0
|
13天前
|
存储 Java 程序员
Python和C++在内存管理方面有什么不同?
【7月更文挑战第2天】Python和C++在内存管理方面有什么不同?
13 0
|
13天前
|
Java C++ 开发者
如何根据项目需求选择使用C++还是Python进行内存管理?
【7月更文挑战第2天】如何根据项目需求选择使用C++还是Python进行内存管理?
17 0
|
13天前
|
算法 Java C++
C++和Python在内存分配策略上的主要区别是什么?
【7月更文挑战第2天】C++和Python在内存分配策略上的主要区别是什么?
12 0
|
13天前
|
Java 程序员 C++
C++和Python在内存分配、释放以及垃圾回收机制上有何不同?
【7月更文挑战第2天】C++和Python在内存分配、释放以及垃圾回收机制上有何不同?
11 0
|
13天前
|
存储 程序员 C++
|
13天前
|
存储 安全 程序员