C++动态分配内存知识点!

news2024/10/7 5:30:16

个人主页:PingdiGuo_guo

收录专栏:C++干货专栏

大家好呀,又是分享干货的时间,今天我们来学习一下动态分配内存。

文章目录

1.动态分配内存的思想

2.动态分配内存的概念

2.1内存分配函数

2.2动态内存的申请和释放

2.3内存碎片问题

3.动态分配内存的作用

3.1 灵活分配内存空间

3.2 提高内存利用率

3.3 动态数据结构的实现

3.4 避免内存溢出和内存泄漏

3.5 提高程序的性能

3.6 总结

4.动态分配内存的实现

4.1 步骤

4.1.1 确定需要分配的内存大小

4.1.2 使用new操作符分配内存

4.1.3 检查分配是否成功

4.1.4 使用分配的内存

4.2 代码示例

5.动态分配内存的分类及代码

5.1 动态分配单个对象的内存

5.1.1 介绍

5.1.2 代码示例

5.2 动态分配对象数组的内存

5.2.1 介绍

5.2.2 代码示例

5.3 注意事项

6.动态分配内存的练习

6.1 题目描述

6.2 知识点

6.3 步骤

6.3.1 初始化

6.3.2 输入数组大小

6.3.3 分配内存

6.3.4 输入字符串内容

6.3.5 显示字符串内容

6.3.6 用户选择

6.3.7 释放内存

6.3.8 结束程序

6.4 代码

7.总结


1.动态分配内存的思想

动态分配内存是指在程序运行时根据需要动态地分配内存空间。这相对于静态分配内存来说,静态分配内存是在编译时固定地分配内存空间,而动态分配内存可以在程序运行期间根据实际需求进行内存的申请和释放,以提高内存的利用率和灵活性。

2.动态分配内存的概念

动态分配内存的概念包括以下几个方面:

2.1内存分配函数

动态分配内存需要使用内存分配函数,如C语言中的malloc()、calloc()、realloc()等,这些函数可以根据需要在运行时动态地分配一块连续的内存空间。

2.2动态内存的申请和释放

使用内存分配函数可以申请一块指定大小的内存空间,申请的内存空间可以在程序运行期间使用。使用完毕后,可以使用释放函数将内存空间释放,以便其他程序继续使用。

2.3内存碎片问题

动态分配内存可能会导致内存碎片问题。当频繁地进行内存分配和释放操作时,可能会在内存中留下一些未被使用的小块内存,这些小块内存无法被再次利用,导致内存的浪费。为了解决内存碎片问题,可以使用内存管理算法来进行内存的分配和释放操作。

3.动态分配内存的作用

动态分配内存在计算机编程中有很多重要的作用,包括:

3.1 灵活分配内存空间

动态分配内存可以根据程序的实际需求,在运行时动态地申请适当大小的内存空间。这使得程序可以根据具体情况来分配所需的内存,提高了程序的灵活性和适应性。

3.2 提高内存利用率

动态分配内存可以避免静态分配内存的固定大小限制,可以根据实际需要进行灵活的内存分配。这样可以更有效地利用内存资源,避免了内存的浪费。

3.3 动态数据结构的实现

动态分配内存是实现动态数据结构(如链表、树等)的基础。动态数据结构的大小可能在程序运行过程中变化,需要动态地为其分配和释放内存空间。

3.4 避免内存溢出和内存泄漏

动态分配内存可以避免程序因为内存空间不足而导致的内存溢出错误。同时,使用动态分配内存还可以确保内存的正确释放,避免造成内存泄漏问题。

3.5 提高程序的性能

动态分配内存可以减少内存碎片的问题,提高内存的利用效率。同时,动态分配内存也可以减少静态分配内存的开销,提高程序的性能。

3.6 总结

总之,动态分配内存在计算机编程中具有重要的作用,它可以提供灵活的内存分配方式,提高内存的利用率,支持动态数据结构的实现,避免内存溢出和内存泄漏问题,同时提高程序的性能。

4.动态分配内存的实现

在C++中,动态内存分配通常使用new和delete操作符来完成。下面我将分步骤和代码两部分来介绍如何进行动态内存分配。



4.1 步骤

4.1.1 确定需要分配的内存大小

首先,你需要确定要分配多少内存。这通常取决于你要存储的数据类型以及你要存储多少这样的数据。


4.1.2 使用new操作符分配内存

使用new操作符来分配内存。例如,如果你要分配一个整数数组,你可以使用new int[size],其中size是你想要的数组大小。


4.1.3 检查分配是否成功

new操作符在无法分配所需内存时会返回nullptr。因此,你应该检查返回的指针是否为nullptr,以确保内存已成功分配。


4.1.4 使用分配的内存

一旦内存成功分配,你就可以开始使用它。例如,你可以将值存储在数组中,或者创建对象等。
释放内存:当你不再需要分配的内存时,应使用delete或delete[]操作符来释放它。忘记释放内存会导致内存泄漏,这是一个常见的编程错误。


4.2 代码示例


下面是一个简单的代码示例,演示了如何在C++中动态分配和释放内存:

 

#include <iostream>

int main() {
// 步骤1:确定需要分配的内存大小
const int size = 10;

// 步骤2:使用new操作符分配内存
int* array = new int[size];

// 检查分配是否成功
if (array == nullptr) {
std::cerr << "Memory allocation failed!" << std::endl;
return 1; // 返回错误代码
}

// 步骤3:使用分配的内存
for (int i = 0; i < size; ++i) {
array[i] = i;
}

// 打印数组内容
for (int i = 0; i < size; ++i) {
std::cout << array[i] << " ";
}
std::cout << std::endl;

// 步骤4:释放内存
delete[] array;

return 0;
}


在这个示例中,我们首先确定要分配的内存大小(一个包含10个整数的数组)。然后,我们使用new操作符分配内存,并检查是否成功。接着,我们使用分配的内存来存储值,并打印数组的内容。最后,我们使用delete[]操作符来释放内存。

5.动态分配内存的分类及代码

在C++中,动态内存分配可以分为两类:动态分配单个对象的内存和动态分配对象数组的内存。



5.1 动态分配单个对象的内存


当你知道需要创建一个对象,但不知道它的生命周期时,可以使用new操作符动态地为其分配内存。这种分配方式在对象的大小不是固定大小时特别有用。



5.1.1 介绍


使用new为单个对象分配内存时,你需要指定对象的类型。new会返回指向新创建对象的指针。如果内存分配成功,你可以使用这个指针来访问和操作对象。如果内存分配失败,new会返回nullptr。



5.1.2 代码示例

 

#include <iostream>

class MyClass {
public:
MyClass(int value) : value_(value) {}
void printValue() { std::cout << value_ << std::endl; }
private:
int value_;
};

int main() {
// 动态分配单个对象的内存
MyClass* obj = new MyClass(42);

// 使用对象
obj->printValue();

// 释放内存
delete obj;

return 0;
}


5.2 动态分配对象数组的内存


当你需要创建多个同类型的对象时,可以使用new操作符来动态分配一个对象数组。这种方式在你不确定数组大小,或者数组大小在运行时才能确定时非常有用。



5.2.1 介绍



使用new为对象数组分配内存时,你需要指定对象的类型和数组的大小。new会返回一个指向数组第一个元素的指针。与单个对象不同,当你使用new为数组分配内存时,需要使用delete[]来释放内存。



5.2.2 代码示例

 

#include <iostream>

class MyClass {
public:
MyClass(int value) : value_(value) {}
void printValue() { std::cout << value_ << std::endl; }
private:
int value_;
};

int main() {
// 动态分配对象数组的内存
const int arraySize = 5;
MyClass* array = new MyClass[arraySize];

// 初始化数组中的对象
for (int i = 0; i < arraySize; ++i) {
array[i] = MyClass(i * 10);
}

// 使用数组中的对象
for (int i = 0; i < arraySize; ++i) {
array[i].printValue();
}

// 释放内存
delete[] array;

return 0;
}


在上面的示例中,我们动态地创建了一个包含5个MyClass对象的数组,并分别初始化了它们。之后,我们遍历数组并打印每个对象的值。最后,我们使用delete[]释放了整个数组所占用的内存。



5.3 注意事项

1.使用new分配的内存必须使用delete或delete[]来释放,否则会导致内存泄漏。
2.new和delete是配对使用的,new[]和delete[]也是配对使用的。不应该混合使用它们,因为这会导致未定义的行为。
3.在使用new分配内存后,总是应该检查返回的指针是否为nullptr,以确保内存分配成功。
4.在C++11及以后的版本中,推荐使用智能指针(如std::unique_ptr和std::shared_ptr)来管理动态分配的内存,以自动处理内存释放,减少内存泄漏的风险。

6.动态分配内存的练习

6.1 题目描述



创建一个程序,该程序使用动态内存分配来创建一个字符串数组。用户将首先输入数组的大小,然后为每个字符串元素输入具体的字符串内容。程序将显示所有输入的字符串,并允许用户选择是否继续添加更多字符串或释放内存并退出程序。


6.2 知识点



动态内存分配与释放(new、delete[])
字符串处理(std::string):C++字符串详解
用户输入和输出(std::cin、std::cout)
循环结构(while、for):C++循环:简化重复的代码
条件语句(if、else):C++分支语句


6.3 步骤



6.3.1 初始化

设置必要的变量和标志,如数组大小、当前索引、是否继续的标志等。



6.3.2 输入数组大小

提示用户输入字符串数组的大小,并读取输入。



6.3.3 分配内存

使用new[]为字符串数组分配内存。



6.3.4 输入字符串内容

使用循环让用户为每个数组元素输入字符串内容。



6.3.5 显示字符串内容

使用循环显示所有输入的字符串。



6.3.6 用户选择

提供选项让用户决定是否继续添加字符串或退出程序。



6.3.7 释放内存

如果用户选择退出,释放已分配的内存。



6.3.8 结束程序

退出程序。



6.4 代码

 

#include <iostream>
#include <string>

int main() {
int size;
std::cout << "Enter the size of the string array: ";
std::cin >> size;

if (size <= 0) {
std::cerr << "Invalid array size. Size must be a positive integer." << std::endl;
return 1;
}

std::string* arr = new std::string[size];
if (arr == nullptr) {
std::cerr << "Memory allocation failed!" << std::endl;
return 1;
}

// 输入字符串内容
std::cout << "Enter " << size << " strings for the array:" << std::endl;
for (int i = 0; i < size; ++i) {
std::cin >> arr[i];
}

// 显示字符串内容
std::cout << "The array contents are:" << std::endl;
for (int i = 0; i < size; ++i) {
std::cout << arr[i] << std::endl;
}

// 用户选择
char choice;
do {
std::cout << "Do you want to continue adding more strings? (y/n): ";
std::cin >> choice;
std::cin.ignore(); // 忽略换行符

if (choice == 'y' || choice == 'Y') {
// 如果用户选择继续,再次分配内存并输入字符串
size *= 2; // 假设我们每次翻倍
std::string* newArr = new std::string[size];
for (int i = 0; i < size / 2; ++i) {
newArr[i] = arr[i];
}
delete[] arr;
arr = newArr;

std::cout << "Enter " << size / 2 << " additional strings:" << std::endl;
for (int i = size / 2; i < size; ++i) {
std::cin >> arr[i];
}

// 再次显示字符串内容(可选)
// ...

} else if (choice == 'n' || choice == 'N') {
// 如果用户选择退出,释放内存并退出程序
std::cout << "Exiting program." << std::endl;
break;
} else {
std::cout << "Invalid choice. Please enter 'y' or 'n': " << std::endl;
}
} while (true);

// 释放内存
delete[] arr;

return 0;
}


这个程序演示了如何动态分配内存来创建一个字符串数组,如何让用户输入字符串内容,如何根据用户的选择动态调整数组大小,以及如何释放内存。同时,它也展示了基本的错误处理和用户交互。

7.总结

本篇博客到这里就结束了,感谢大家的支持与观看,如果有好的建议欢迎留言,谢谢大家啦!

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

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

相关文章

新手学习Cesium的几点建议

Cesium是当前非常火热的三维数字地球开发框架&#xff0c;很多公司基于Cesium做项目以及形成了自己的产品&#xff0c;关于Cesium的学习&#xff0c;有诸多网站、书籍、学习资料甚至培训教材&#xff0c;这里不再详细推荐&#xff0c;从学习Cesium的角度&#xff0c;资料和教程…

web开发中的长度单位详解

1、长度单位包括哪些&#xff1f; 长度单位&#xff1a;例如&#xff0c;厘米、毫米、英寸。还有像素&#xff08;px&#xff09;&#xff0c;元素的字体高度&#xff08;em&#xff09;、字母x的高度&#xff08;ex&#xff09;、百分比&#xff08;%&#xff09;等这些单位&…

[ 2024春节 Flink打卡 ] -- Paimon

2024&#xff0c;游子未归乡。工作需要&#xff0c;flink coding。觉知此事要躬行&#xff0c;未休&#xff0c;特记 Flink 社区希望能够将 Flink 的 Streaming 实时计算能力和 Lakehouse 新架构优势进一步结合&#xff0c;推出新一代的 Streaming Lakehouse 技术&#xff0c;…

MySQL加锁策略详解

我们主要从三个方面来讨论这个问题&#xff1a; 啥时候加&#xff1f;如何加&#xff1f;什么时候该加什么时候不该加&#xff1f; 1、啥时候加 1.1 显式锁 MySQL 的加锁可以分为显式加锁和隐式加锁&#xff0c;显式加锁我们比较好识别的&#xff0c;因为他往往直接体现在 S…

25-k8s集群中-RBAC用户角色资源权限

一、RBAC概述 1&#xff0c;k8s集群的交互逻辑&#xff08;简单了解&#xff09; 我们通过k8s各组件架构&#xff0c;指导各个组件之间是使用https进行数据加密及交互的&#xff0c;那么同理&#xff0c;我们作为“使用”k8s的各种资源&#xff0c;也是通过https进行数据加密的…

4 编写达梦插件包

1、初始化达梦数据库 具体脚本可以参考: https://github.com/nacos-group/nacos-plugin/blob/develop/nacos-datasource-plugin-ext/nacos-dm-datasource-plugin-ext/src/main/resources/schema/nacos-dm.sql

国际阿里云,想要使用怎么解决支付问题

在国内我们很多时候都需要用到国际阿里云&#xff0c;在国际阿里云需要使用就需要支付&#xff0c;自己办理visa卡比较麻烦&#xff0c;那么我们可以使用虚拟卡&#xff0c;虚拟卡办理快速简单 真实测评使用Fomepay的5347支持国际阿里云的支付&#xff0c;秒下卡&#xff0c;不…

Talk|北京大学杨灵:扩散模型的算法创新与领域应用

本期为TechBeat人工智能社区第572期线上Talk。 北京时间2月21日(周三)20:00&#xff0c;北京大学博士生—杨灵的Talk已准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “扩散模型的算法创新与领域应用”&#xff0c;系统地介绍了他的团队基于扩散模型的算法…

vue3在router跳转路由时,params失效问题

vue-router重要提示。 解决方案&#xff1a; 1. 使用query传参 但是变量会直接暴露在url中 2.用store或localStorage这种办法暂存一下。

书生·浦语大模型实战营第二节课作业

使用 InternLM-Chat-7B 模型生成 300 字的小故事&#xff08;基础作业1&#xff09;。 熟悉 hugging face 下载功能&#xff0c;使用 huggingface_hub python 包&#xff0c;下载 InternLM-20B 的 config.json 文件到本地&#xff08;基础作业2&#xff09;。 下载过程 进阶…

Vue+SpringBoot打造校园二手交易系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手商品档案管理模块2.3 商品预约管理模块2.4 商品预定管理模块2.5 商品留言板管理模块2.6 商品资讯管理模块 三、实体类设计3.1 用户表3.2 二手商品表3.3 商品预约表3.4 商品预定表3.5 留言表3.6 资讯…

蓝桥杯备赛系列——倒计时50天!

蓝桥杯备赛系列 倒计时50天&#xff01; 前缀和和差分 知识点 **前缀和数组&#xff1a;**假设原数组用a[i]表示&#xff0c;前缀和数组用sum[i]表示&#xff0c;那么sum[i]表示的是原数组前i项之和&#xff0c;注意一般用前缀和数组时&#xff0c;原数组a[i]的有效下标是从…

PotPlayer+Alist挂载并播放网盘视频

文章目录 说明技术WebDAVPotPlayer 操作步骤一&#xff1a;Alist开启WebDAV代理二&#xff1a;PotPlayer连接Alist 说明 Alist网页端播放视频受限&#xff0c;主要是文件大于20MB&#xff0c;由于官方限制&#xff0c;无法播放需要使用user-agent修改插件&#xff0c;设置百度…

ES项目应用

配置: ES存储了2-3亿条&#xff0c;几百GB ES集群有5 个节点 2主2副 ES返回数据量窗口大小设置 index.max_result_window 深度翻页 1.from size 方式 2.scroll相当于维护了一份当前索引段的快照信息&#xff0c;这个快照信息是你执行这个scroll查询时的快照。在这个查询后的任…

【selenium】八大元素定位方式|xpath css id name...

目录 一、基础元素定位 二、cssSelector元素定位——通过元素属性定位 三、xpath元素定位——通过路径 1 、xpath绝对定位 &#xff08;用的不多&#xff09; 缺点&#xff1a;一旦页面结构发生变化&#xff08;比如重新设计时&#xff0c;路径少两节&#xff09;&#x…

跨境电商营销推广:法律合规指引与风险管理策略

在全球数字化时代&#xff0c;跨境电商正成为国际贸易的重要组成部分。然而&#xff0c;在跨境电商的营销推广过程中&#xff0c;合规问题不容忽视。为了避免法律纠纷&#xff0c;企业需要了解并遵守各国的法律法规。本文将深入探讨跨境电商在营销推广中需要遵守的法律法规&…

Android 面试问题 2024 版(其二)

Android 面试问题 2024 版&#xff08;其二&#xff09; 六、多线程和并发七、性能优化八、测试九、安全十、Material设计和 **UX/UI** 六、多线程和并发 Android 中的进程和线程有什么区别&#xff1f; 答&#xff1a;进程是在自己的内存空间中运行的应用程序的单独实例&…

数据分析(二)自动生成分析报告

1. 报告生成思路概述 怎么快速一份简单的数据分析报告&#xff0c;注意这个报告的特点&#xff1a; --网页版&#xff0c;可以支持在线观看或者分享HTML文件 --标题&#xff0c;动图&#xff0c;原始数据应有尽有 --支持交互&#xff0c;比如plotly交互画面&#xff0c;数据…

leetcode hot100单词拆分

在本题中&#xff0c;我们是要把一个字符串&#xff0c;判断是否能用给的字符串数组中的单词进行拆分&#xff0c;如果可以则返回true&#xff0c;不能的话则返回false。这个题一开始看无法与背包问题联系在一起。但仔细考虑&#xff0c;就是用物品&#xff08;给的字符串数组中…

运维的利器–监控–zabbix–第二步:建设–部署zabbix agent

文章目录 监控客户端部署及添加主机一、在 zabbix-server 安装客户端二、在本机和其他linux主机安装zabbix agent客户端1、安装2、配置3、启动并开机自启4、添加主机创建主机组创建主机等一会或重启zabbix-server查看配置是否成功 三、在其他windows上安装zabbix agent客户端下…