C++初阶--内存管理

简介: C++初阶--内存管理


内存分布

栈(stack):栈是由编译器自动管理的内存区域,用于存储局部变量,函数参数和函数调用信息等。栈的特点是后进先出,它的生命周期与函数的调用关系密切联系。当函数调用结束后,栈上的局部变量会被自动销毁

堆(heap):堆是由程序员手动管理的动态内存区域,用于存储动态分配的对象。通过使用new/delete等操作符来手动申请和释放堆上的内存。堆上的内存生命周期由程序员来负责控制,需要手动释放以避免内存泄漏。

全局存储区(data):全局存储区用于存储全局变量和静态变量。全局变量在程序运行期间一直存在,静态变量具有生命周期,即从声明到程序结束都存在。全局存储区的内存由编译器在程序开始时进行分配,在程序结束时进行自动释放

常量存储区(cost):常量存储区用于存储常量值,例如字符串常量,数字等。这部分内存通常是只读的,不可修改。

new/delete

在C语言中,我们是用malloc和free来进行动态内存管理的,而在C++中,我们习惯使用new/delete来进行动态内存管理。

基本用法

class A
{
private:
  int _a;
public:
  A(int a=0)
    :_a(a)
  {
    cout << "A()" << endl;
  }
  ~A()
  {
    cout << "~A()" << endl;
  }
};
int main()
{
  //new
  int* p1 = new int;
  *p1 = 20;
  int* p2 = new int[10];
  p2[0] = 1;
  p2[1] = 2;
  int* p3 = new int(4);
  int* p4 = new int[10] {1, 2, 3};
  delete p1;
  delete[] p2;
  delete p3;
  delete[] p4;
  //对于自定义类型来说
  //new的本质:开空间+使用构造函数
  A aa1;
  A aa2;
  A aa3;
  A* p5 = new A[3]{ aa1,aa2,aa3 };
  A* p6 = new A[3];
  A* p7 = new A[3]{ A(1),A(2),A(3) };
  A* p8 = new A[3]{ 1,2,3 };
  delete[] p5;
  delete[] p6;
  delete[] p7;
  delete[] p8;
  return 0;
}

基本用法:

有自定义类型时:

malloc/free和new/delete的区别

进一步理解

class Stack 
{
private:
  int* _a;
  int _top;
  int _capacity;
public:
  Stack(int capacity = 4)
    :_a(new int[capacity]),
    _top(0),
    _capacity(capacity)
  {
    cout << "Stack(int capacity):" << endl;
  }
  ~Stack()
  {
    cout << "~Stack()" << endl;
    delete[] _a;
    _a = nullptr;
    _top = 0;
    _capacity = 0;
  }
};
int main()
{
  Stack* p1 = new Stack;
  delete p1;
  Stack* p2 = (Stack*)operator new(sizeof(Stack));
  operator delete(p2);
  Stack* p3 = new Stack[10];
  //delete[] p3;
  delete p3;
  A* p4 = new A[10];
  delete p4;
  return 0;
}

空间的开辟:

操作数new和delete:

当把析构函数屏蔽了,使用delete p3,为什么可以通过编译:

*

new和delete的实现原理

定位new(了解)

定位new是一种特殊的用法,用于在指定的内存位置上创建对象。通常情况下,使用new关键字会在堆内存中动态分配一块适当的空间大小,并在该内存上构造一个对象。而定位new则允许我们预先分配一块内存,并在该内存上构造对象

语法形式:new(address)Type(arguments)

int main()
{
  A* p1 = (A*)operator new(sizeof(A));
  //不能显示调用构造函数
  //p1->A(1);
  //可以这样操作
  new(p1)A(1);
  //析构函数可以显示调用
  p1->~A();
  operator delete(p1);
}

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