C/C++内存管理(上)

简介: C/C++内存管理(上)

前言

本节内容将对C与C++的内存管理方面的知识进行分析和解释。

1.C/C++内存分布

在这里,我们先对C语言的内存分布进行一个回顾。

看下面的一段代码和相关问题 :

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);
}

选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)

globalVar在哪里?__C__

staticGlobalVar在哪里?_C___

staticVar在哪里?__C__

localVar在哪里?___A_

num1 在哪里?__A__

char2在哪里?__A__

*char2在哪里?__A_

pChar3在哪里?__A__

*pChar3在哪里?___D

ptr1在哪里?_A___

*ptr1在哪里?__B__

详细的图解如下

【说明】

1. 又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。

2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口

创建共享共享内存,做进程间通信。(Linux课程如果没学到这块,现在只需要了解一下)

3. 用于程序运行时动态内存分配,堆是可以上增长的。

4. 数据段--存储全局数据和静态数据。

5. 代码段--可执行的代码/只读常量。

2.C语言中动态内存管理方式:malloc/calloc/realloc/free (回顾)

void Test ()
{
// 1.malloc/calloc/realloc的区别是什么?
int* p2 = (int*)calloc(4, sizeof (int));
int* p3 = (int*)realloc(p2, sizeof(int)*10);
// 这里需要free(p2)吗?
free(p3 );
}

1. malloc:

- 语法:void* malloc(size_t size);

- 功能:分配指定字节数的内存,但不会初始化内存。分配的内存包含不确定的值。

- 示例:int* p = (int*)malloc(4 * sizeof(int));

2. calloc:

- 语法:void* calloc(size_t num, size_t size);

- 功能:分配内存用于数组,并初始化所有位为0。num`是元素数量,size是每个元素的大小。

- 示例:int* p = (int*)calloc(4, sizeof(int));(分配4个整数并初始化为0)

3. realloc:

- 语法:void* realloc(void* ptr, size_t size);

- 功能:重新调整已分配内存的大小。如果 ptr 是 NULL,效果等同于 malloc;如果 size 为0,用法等同于 `free`。如果扩展内存,原有数据将被保留。

- 示例:int* p = (int*)realloc(p2, sizeof(int) * 10);` 对于你的代码片段:

不用释放p2

- 使用 calloc 分配内存后,p2指向这块内存。 - 当你使用 `realloc` 调整 `p2` 的大小时,`realloc` 会返回一个新的指针 `p3`,如果内存调整成功,原来 `p2` 的内存会被释放,因此你不需要再对 `p2` 调用 `free`。

3.C++内存管理方式

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因

此C++又提出了自己的内存管理方式: 通过 new delete 操作符进行动态内存管理

3.1new/delete操作内置类型

#include <iostream>
using namespace std;
int main() {
  //动态申请一个int类型的空间并初始化为520
  int* p1 = new int(520);
   动态申请3个int类型的空间并初始化
  int* p2 = new int[3] {1, 2, 3};
  cout << *p1 << endl;
  for (int i = 0; i < 3; ++i) {
    cout << "p2[" << i << "]: " << p2[i] << endl;
  }
  // 释放内存
  delete p1;
  delete[] p2;
 
  return 0;
}

注意事项

  • 内存管理:
  • 动态分配的内存需要手动释放,以防止内存泄漏。
  • 使用 delete 释放单个对象内存,使用 delete[] 释放数组内存。
  • 初始化方式:
  • 在 C++11 及以后,可以使用初始化列表对动态数组进行初始化,如你所示的 {1, 2, 3}
  • 在较旧的 C++ 版本中,动态数组的初始化可以通过循环来完成,因为不支持在 new 语句中直接初始化数组。

3.2new/delete操作自定义类型

#include <iostream>
using namespace std;
class A {
public:
  A(int a=0 , int b=0)
    :_a(a), _b(b) {
    cout << "A(int a = 0, int b = 0)" << endl;
  }
  ~A(){
    cout << "~A()" << endl;
}
 
//void Print(){
//  cout << "A::Print->" << _a << endl;
//}
private:
  int _a = 1;
  int _b = 1;
};
int main()
{
  
  A* p1 = new A(520);
  A* p2 = new A(520,1314);
  delete p1;
  delete p2;
  //该自定义类型初始化方法
  A aa1(1, 1);
  A aa2(2, 2);
  A aa3(3, 3);
    A* p3 = new A[3]{aa1, aa2, aa3};
  delete[]p3;
  //匿名初始化
  A* p4 = new A[3]{ A(1,1), A(2,2), A(3,3)};
  delete[]p4;
  //列表初始化
  A* p5 = new A[3]{ {1,1}, {2,2}, {3,3} };
  
  delete []p5;
  
  return 0;
}
 

注意:在申请自定义类型的空间时, new 会调用构造函数, delete 会调用析构函数,而 malloc

free 不会


C/C++内存管理(下):https://developer.aliyun.com/article/1624948

目录
相关文章
|
2月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
29天前
|
存储 缓存 C语言
【c++】动态内存管理
本文介绍了C++中动态内存管理的新方式——`new`和`delete`操作符,详细探讨了它们的使用方法及与C语言中`malloc`/`free`的区别。文章首先回顾了C语言中的动态内存管理,接着通过代码实例展示了`new`和`delete`的基本用法,包括对内置类型和自定义类型的动态内存分配与释放。此外,文章还深入解析了`operator new`和`operator delete`的底层实现,以及定位new表达式的应用,最后总结了`malloc`/`free`与`new`/`delete`的主要差异。
49 3
|
1月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
86 4
|
2月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
148 21
|
2月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
2月前
|
存储 C语言 C++
【C++打怪之路Lv6】-- 内存管理
【C++打怪之路Lv6】-- 内存管理
47 0
【C++打怪之路Lv6】-- 内存管理
|
2月前
|
存储 C语言 C++
【C/C++内存管理】——我与C++的不解之缘(六)
【C/C++内存管理】——我与C++的不解之缘(六)
|
2月前
|
程序员 C语言 C++
C++入门5——C/C++动态内存管理(new与delete)
C++入门5——C/C++动态内存管理(new与delete)
81 1
|
2月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
336 1
|
2月前
|
存储 安全 程序员
【C++篇】深入内存迷宫:C/C++ 高效内存管理全揭秘
【C++篇】深入内存迷宫:C/C++ 高效内存管理全揭秘
86 3