C++---------动态内存管理

以下是对 C++ 中相关概念的详细说明及代码示例:

一、动态分配和堆

  1. new 操作符
    • new 操作符用于在堆上动态分配内存。它会调用对象的构造函数(如果是类对象)并返回指向分配内存的指针。
    • 示例:
#include <iostream>
using namespace std;int main() {// 为一个整数分配内存int* p = new int;*p = 10;cout << *p << endl;// 释放内存delete p;return 0;
}
- 代码解释:- `int* p = new int;`:使用 `new` 操作符在堆上分配了足够存储一个 `int` 的内存空间,并将该内存地址存储在指针 `p` 中。- `*p = 10;`:将值 `10` 存储到 `p` 所指向的内存中。- `delete p;`:使用 `delete` 操作符释放之前分配的内存,防止内存泄漏。
  1. 动态数组
    • 使用 new 操作符可以创建动态数组,需要使用 delete[] 来释放。
    • 示例:
#include <iostream>
using namespace std;int main() {int size = 5;// 为包含 5 个整数的数组分配内存int* arr = new int[size];for (int i = 0; i < size; ++i) {arr[i] = i * 2;}for (int i = 0; i < size; ++i) {cout << arr[i] << " ";}cout << endl;// 释放动态数组内存delete[] arr;return 0;
}
- 代码解释:- `int* arr = new int[size];`:在堆上分配了一个包含 `size` 个 `int` 元素的数组。- `for (int i = 0; i < size; ++i) { arr[i] = i * 2; }`:为数组元素赋值。- `delete[] arr;`:使用 `delete[]` 操作符释放动态数组的内存。

在这里插入图片描述

  1. 动态对象
    • 对于类对象,使用 new 操作符可以动态创建对象,同时会调用对象的构造函数。
    • 示例:
#include <iostream>
using namespace std;class MyClass {
public:MyClass() {cout << "MyClass object is created." << endl;}~MyClass() {cout << "MyClass object is destroyed." << endl;}
};int main() {// 动态创建 MyClass 对象MyClass* obj = new MyClass();// 释放对象内存delete obj;return 0;
}
- 代码解释:- `MyClass* obj = new MyClass();`:在堆上创建 `MyClass` 的对象,调用其构造函数。- `delete obj;`:调用对象的析构函数并释放内存。

二、链表

  1. 链表内的迭代
    • 链表是一种动态数据结构,由节点组成,每个节点包含数据和指向下一个节点的指针。
    • 示例:
#include <iostream>
using namespace std;struct Node {int data;Node* next;Node(int d) : data(d), next(nullptr) {}
};int main() {Node* head = new Node(1);Node* second = new Node(2);Node* third = new Node(3);head->next = second;second->next = third;// 迭代链表Node* curr = head;while (curr!= nullptr) {cout << curr->data << " ";curr = curr->next;}cout << endl;// 释放链表内存curr = head;while (curr!= nullptr) {Node* temp = curr;curr = curr->next;delete temp;}return 0;
}
- 代码解释:- `Node` 结构体定义了链表的节点,包含 `data` 和 `next` 指针。- `head->next = second;` 和 `second->next = third;` 建立了链表的链接。- `while (curr!= nullptr) { cout << curr->data << " "; curr = curr->next; }`:通过迭代遍历链表并输出数据。- `while (curr!= nullptr) { Node* temp = curr; curr = curr->next; delete temp; }`:释放链表节点的内存。
  1. 递归和列表
    • 可以使用递归方法来处理链表,例如计算链表长度。
    • 示例:
#include <iostream>
using namespace std;struct Node {int data;Node* next;Node(int d) : data(d), next(nullptr) {}
};// 递归计算链表长度
int length(Node* head) {if (head == nullptr) return 0;return 1 + length(head->next);
}int main() {Node* head = new Node(1);Node* second = new Node(2);Node* third = new Node(3);head->next = second;second->next = third;cout << "Length of the list: " << length(head) << endl;// 释放链表内存Node* curr = head;while (curr!= nullptr) {Node* temp = curr;curr = curr->next;delete temp;}return 0;
}
- 代码解释:- `length(Node* head)` 函数使用递归方法计算链表的长度,通过不断递归调用 `length(head->next)` 直到 `head` 为 `nullptr`。

三、释放内存

  1. delete 操作符

    • 用于释放 new 操作符分配的内存,确保在不再使用动态分配的内存时调用。
    • 对于对象使用 delete,对于数组使用 delete[]
    • 示例见上述动态分配和堆部分。
  2. 释放内存策略

    • 遵循“谁分配谁释放”原则,避免内存泄漏。在异常处理时也要确保正确释放内存。
    • 例如,在函数中分配的内存,在函数结束时或异常抛出时释放:
#include <iostream>
#include <stdexcept>
using namespace std;void func() {int* p = new int;try {// 一些操作*p = 10;if (*p == 10) {throw runtime_error("Error occurred");}delete p;} catch (const exception& e) {delete p;throw;}
}int main() {try {func();} catch (const exception& e) {cout << e.what() << endl;}return 0;
}
- 代码解释:- 在 `func()` 函数中,首先分配内存,在操作过程中可能抛出异常,使用 `try-catch` 确保在异常发生时也能正确释放内存。
  1. 析构函数
    • 析构函数是类的成员函数,当对象销毁时自动调用,用于释放资源。
    • 示例:
#include <iostream>
using namespace std;class MyResource {
public:MyResource() {cout << "Resource acquired." << endl;}~MyResource() {cout << "Resource released." << endl;}
};class MyClass {
private:MyResource* res;
public:MyClass() {res = new MyResource();}~MyClass() {delete res;}
};int main() {MyClass obj;// 当 main 函数结束,obj 的析构函数会被调用,释放资源return 0;
}
- 代码解释:- `MyClass` 的构造函数中创建 `MyResource` 对象,析构函数中释放该对象,确保资源的释放。

四、定义 charstack 类

  1. charstack.h 接口
// charstack.h
#ifndef CHARSTACK_H
#define CHARSTACK_Hclass CharStack {
private:char* stack;int top;int capacity;void resize();
public:CharStack();~CharStack();void push(char c);char pop();bool isEmpty() const;bool isFull() const;
};#endif
  1. 选择字符栈的表示
    • 这里选择动态数组表示字符栈,实现 charstack.cpp 如下:
// charstack.cpp
#include "charstack.h"
#include <iostream>CharStack::CharStack() : top(-1), capacity(10) {stack = new char[capacity];
}CharStack::~CharStack() {delete[] stack;
}void CharStack::push(char c) {if (isFull()) {resize();}stack[++top] = c;
}char CharStack::pop() {if (isEmpty()) {throw out_of_range("Stack is empty.");}return stack[top--];
}bool CharStack::isEmpty() const {return top == -1;
}bool CharStack::isFull() const {return top == capacity - 1;
}void CharStack::resize() {capacity = capacity * 2;char* newStack = new char[capacity];for (int i = 0; i <= top; ++i) {newStack[i] = stack[i];}delete[] stack;stack = newStack;
}
- 代码解释:- `CharStack` 类使用动态数组存储字符元素。- `push(char c)` 方法将元素入栈,如果栈满调用 `resize()` 方法扩容。- `pop()` 方法将元素出栈,如果栈空抛出异常。- `resize()` 方法将栈的容量翻倍并复制元素到新的内存中。

在使用这些代码时,需要注意内存的分配和释放,避免出现内存泄漏。同时,对于类的设计,析构函数的正确使用可以确保资源的正确释放,以保证程序的健壮性和内存使用的合理性。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/65209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

R语言数据分析案例46-不同区域教育情况回归分析和探索

一、研究背景 教育是社会发展的基石&#xff0c;对国家和地区的经济、文化以及社会进步起着至关重要的作用。在全球一体化进程加速的今天&#xff0c;不同区域的教育发展水平呈现出多样化的态势。这种差异不仅体现在教育资源的分配上&#xff0c;还表现在教育成果、教育投入与…

单机和微服务的区别,微服务有什么问题?数据一致性问题怎么解决?幂等问题怎么解决?

单机和微服务的区别&#xff0c;微服务有什么问题&#xff1f;数据一致性问题怎么解决&#xff1f;幂等问题怎么解决&#xff1f; 单机架构和微服务架构在设计理念、部署和扩展性上有显著区别。 单机架构 vs 微服务架构 单机架构 定义&#xff1a;所有组件&#xff08;前端…

基于springboot+vue实现的卷烟营销统计分析系统 (源码+L文+ppt)4-129

摘 要 卷烟行业的快速发展使得卷烟营销统计分析系统成为了一个必不可少的工具。基于Java的卷烟营销统计分析系统旨在提供高效、准确和便捷的适用卷烟营销服务。本文讲述了基于java语言开发&#xff0c;后台数据库选择MySQL进行数据的存储。该软件的主要功能是进行卷烟营销统计…

mac启ssh服务用于快速文件传输

x.1 在mac上启SSH服务 方法一&#xff1a;图形交互界面启ssh&#xff08;推荐&#xff09; 通过sharing - advanced - remote login来启动ssh&#xff1b;&#xff08;中文版mac应该是 “系统设置 → 通用 → 共享”里打开“远程登录”来启动&#xff09; 查看自己的用户名和…

青蛇人工智能学家

青蛇人工智能学家 青蛇&#xff0c;是蓝星上&#xff0c;最出名的人工智能学家。 在蓝星上&#xff0c;大家都知道&#xff0c;青蛇人工智能学家&#xff0c;最大的爱好&#xff0c;是美食。 青蛇人工智能学家&#xff0c;对自己的食物&#xff0c;非常在意&#xff0c;对自己的…

[c++进阶(三)]单例模式及特殊类的设计

1.前言 在实际场景中,总会遇见一些特殊情况,比如设计一个类,只能在堆上开辟空间, 或者是设计一个类只能实例化一个对象。那么我们应该如何编写代码呢&#xff1f;本篇将会详细的介绍 本章重点&#xff1a; 本篇文章着重讲解如何设计一些特殊 的类,包括不能被拷贝,只能在栈/堆上…

【LLM论文日更】| 训练大型语言模型在连续潜在空间中进行推理

论文&#xff1a;https://arxiv.org/pdf/2412.06769代码&#xff1a;暂未开源机构 &#xff1a;Meta领域&#xff1a;思维链发表&#xff1a;arxiv 研究背景 研究问题&#xff1a;这篇文章要解决的问题是如何在大语言模型&#xff08;LLMs&#xff09;中实现一种新的推理范式&…

opc da 服务器数据 转 opc ua项目案例

目录 1 案例说明 2 VFBOX网关工作原理 3 应用条件 4 查看OPC DA服务器的相关参数 5 配置网关采集opc da数据 6 用opc ua协议转发采集的数据 7 在服务器上运行仰科OPC DA采集软件 8 案例总结 1 案例说明 在OPC DA服务器上运行OPC DA client软件查看OPC DA服务器的相关参…

学习threejs,PerspectiveCamera透视相机和OrthographicCamera正交相机对比

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.PerspectiveCamera透…

PHP后执行php.exe -v命令报错并给出解决方案

文章目录 一、执行php.exe -v命令报错解决方案 一、执行php.exe -v命令报错 -PHP Warning: ‘C:\windows\SYSTEM32\VCRUNTIME140.dll’ 14.38 is not compatible with this PHP build linked with 14.41 in Unknown on line 0 解决方案 当使用PHP8.4.1时遇到VCRUNTIME140.dll…

分布式调度框架学习笔记

一、分布式调度框架的基本设计 二、线程池线程数量设置的基本逻辑 cpu是分时复用的方法&#xff0c;线程是cpu调度的最小单元 如果当前cpu核数是n&#xff0c;计算密集型线程数一般设为n&#xff0c;io密集型(包括磁盘io和网络io)线程数一般设置为2n. 计算密集型线程数一般设…

vue 基础学习

一、ref 和reactive 区别 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><div id"app"><h1>{{Web.title}}</h1><h1&…

CI/CD是什么?

CI/CD 定义 CI/CD 代表持续集成和持续部署&#xff08;或持续交付&#xff09;。它是一套实践和工具&#xff0c;旨在通过自动化构建、测试和部署来改进软件开发流程&#xff0c;使您能够更快、更可靠地交付代码更改。 持续集成 (CI)&#xff1a;在共享存储库中自动构建、测试…

论文阅读:Deep Fusion Clustering Network With Reliable Structure Preservation

论文地址&#xff1a;Deep Fusion Clustering Network With Reliable Structure Preservation | IEEE Journals & Magazine | IEEE Xplore 代码地址&#xff1a;https://github.com/gongleii/DFCN-RSP 摘要 深度聚类通过优雅地利用数据表示来寻找样本的划分&#xff0c;已…

InnoDB存储引擎【MySQL从放弃到入门】

文章目录 InnoDB存储引擎【MySQL从放弃到入门】1.逻辑架构1.1 一条SQL语句是怎么执行的呢&#xff1f;1.2 MySQL存储引擎有哪些&#xff1f; 2.MySQL一行记录是怎么存储的&#xff1f;2.1 NULL值是如何存储的&#xff1f; 3.char和varchar的区别&#xff1f;4.数据页4.1 聚簇索…

Jenkins集成部署(图文教程、超级详细)

一、CI/CD 的概念 ​ CI/CD一般包含三个概念&#xff1a; 持续集成&#xff08;Continuous Integration &#xff0c;CI&#xff09; 持续交付&#xff08;Continuous Delivery&#xff09; 持续部署&#xff08;Continuous Deploy&#xff09; ​ CI/CD 是现代软件开发的重要…

UE5喷涂功能

许多FPS/TPS 游戏都有喷涂、涂鸦功能 其实原理很简单&#xff0c;就是利用了延迟贴花实现的 我们从网上随便找一张图 创建一个材质&#xff0c;材质域选择延迟贴花 混合模式选择半透明&#xff0c;自发光强度可以看感觉调整 材质做好之后编译保存&#xff0c;新建一个Actor…

ECCV-2024 | 指令不够用、大模型来生成!BEVInstructor:基于BEV感知和大模型的视觉语言导航指令生成

作者&#xff1a;Sheng Fan, Rui Liu, Wenguan Wang, and Yi Yang 单位&#xff1a;浙江大学 原文链接&#xff1a;Navigation Instruction Generation with BEV Perception and Large Language Models &#xff08;https://link.springer.com/chapter/10.1007/978-3-031-726…

电脑出现 0x0000007f 蓝屏问题怎么办,参考以下方法尝试解决

电脑蓝屏是让许多用户头疼的问题&#xff0c;其中出现 “0x0000007f” 错误代码更是较为常见且棘手。了解其背后成因并掌握修复方法&#xff0c;能帮我们快速恢复电脑正常运行。 一、可能的硬件原因 内存问题 内存条长时间使用可能出现物理损坏&#xff0c;如金手指氧化、芯片…

Ubuntu下ESP32-IDF开发环境搭建

Ubuntu下ESP32-IDF开发环境搭建 文章目录 Ubuntu下ESP32-IDF开发环境搭建一、前言二、软件安装三、开发环境搭建3.1 ESP-IDF安装&#xff1a;3.2 安装编译工具&#xff1a; 四、编译并烧录代码五、ESP32代码编辑工具 一、前言 ​ 开发ESP32&#xff0c;我们首先就要安装开发环…