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

个人主页: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.rhkb.cn/news/261621.html

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

相关文章

MyBatis小技巧

MyBatis小技巧 一、#{}和${}1.#{}和${}的区别2.什么情况下必须使⽤${} 二、别名机制-typeAliases1.typeAlias2.package 三、mappers的配置1.mapper&#xff08;1&#xff09;resource&#xff08;3&#xff09;URL&#xff08;3&#xff09;class 2.package 四、插⼊数据时获取…

pikachu靶场-CSRF

CSRF: 介绍&#xff1a; Cross-site request forgery简称为"CSRF”。 在CSF的攻击场景中攻击者会伪造一个请求&#xff08;这个请求一般是一个链接&#xff09; 然后欺骗目标用户进行点击&#xff0c;用户一旦点击了这个请求&#xff0c;整个攻击也就完成了&#xff0…

泽攸科普——扫描电子显微镜(SEM)像衬度形成原理

扫描电镜通过电子束在样品表面进行周而复始的扫描运动&#xff0c;同时实时监测各种信号图像的产生&#xff0c;然后根据产生的信号多少来调制图像。 引起各种信号产生的扫描电镜图像衬度的来源有三个方面&#xff1a; 1. 试样本身性质&#xff1a;包括表面的凹凸不平、成分的…

把excel模版保存到文件夹里不走接口进行下载的方法

把excel保存到文件夹不走接口进行下载&#xff0c;一定要注意&#xff0c;需要放到public下的static文件夹下&#xff0c;如果没有static文件夹&#xff0c;就新建一个 &#xff01;&#xff01;&#xff01;不放在static文件夹下可能会报错&#xff0c;提示&#xff1a;无法从…

尾矿库排洪系统结构仿真软件WKStruc(可试用)

1、背景介绍 尾矿库作为重大危险源之一&#xff0c;在国际灾害事故排名中位列第18位&#xff0c;根据中国钼业2019年8月刊《中国尾矿库溃坝与泄漏事故统计及成因分析》的统计&#xff0c;在46起尾矿库泄漏事故中&#xff0c;由于排洪设施导致的尾矿泄漏事故占比高达1/3&#x…

Mysql第二关之存储引擎

简介 所有关于Mysql数据库优化的介绍仿佛都有存储引擎的身影。本文介绍Mysql常用的有MyISAM存储引擎和Innodb存储引擎&#xff0c;还有常见的索引。 Mysql有两种常见的存储引擎&#xff0c;MyISAM和Innodb&#xff0c;它们各有优劣&#xff0c;经过多次优化和迭代&#xff0c;…

基于 QUIC 协议的 HTTP/3 正式发布!

近期&#xff0c;超文本传输协议新版本 HTTP/3 RFC 文档&#xff0c;已由互联网工程任务组&#xff08;IETF&#xff09;对外发布。HTTP/3 全称为 HTTP-over-QUIC&#xff0c;指在 QUIC&#xff08;Quick UDP Internet Connections, 快速 UDP 互联网连接&#xff09;上映射 HTT…

TSINGSEE青犀AI智能分析网关V4初始配置与算法相关配置介绍

TSINGSEE青犀AI智能分析网关V4内置了近40种AI算法模型&#xff0c;支持对接入的视频图像进行人、车、物、行为等实时检测分析&#xff0c;上报识别结果&#xff0c;并能进行语音告警播放。硬件管理平台支持RTSP、GB28181协议、以及厂家私有协议接入&#xff0c;可兼容市面上常见…

CSS基础属性

【三】基础属性 【1】高度和宽度 &#xff08;1&#xff09;参数 width&#xff08;宽度&#xff09;&#xff1a;用于设置元素的宽度。可以使用具体的数值&#xff08;如像素值&#xff09;或百分比来指定宽度。 height&#xff08;高度&#xff09;&#xff1a;用于设置元…

Excel练习:双层图表

Excel练习&#xff1a;双层图表 学习视频Excel制作双层图表&#xff0c;很多人都不会&#xff0c;其实只需1步操作就够了&#xff01;_哔哩哔哩_bilibili ​​ 通过调整两个图形的显示范围实现 增加折现图的负数显示范围&#xff0c;使折现图仅出现在整体图形的上方增加柱形…

白话微机:8.解释FPGA以及一些考研面试问题

一. 前言&#xff08;更新世界观&#xff09; 在“微机世界”&#xff0c;普通的城市(单片机)里&#xff0c;人又有一个别的名字叫做“数据”&#xff0c;人有0有1&#xff1b;人们也有住房&#xff0c;这些住房在这个世界叫做“存储器”&#xff1b;地上有路&#xff0c;这些路…

吴恩达机器学习全课程笔记第三篇

目录 前言 P42-P48 神经元和大脑 神经网络中的层 更复杂的神经网络 前向传播&#xff08;做出预测&#xff09; P49-P53 代码中的推理 构建一个神经网络 P54-P60 矩阵乘法 TensorFlow框架实现神经网络 前言 这是吴恩达机器学习笔记的第三篇&#xff0c;第二篇笔记…

解决elementUI固定列后,下方多了一条横线的问题

最近遇到一个bug,如下图,el-table的操作列使用fixed属性固定后,下方多了一条横线: 我们将样式设置高优先,以覆盖内联样式,如下是less里使用穿透样式解决的办法: <style lang="less" scoped> /deep/ .el-table__fixed-right {height: 100

uni-app 开发调试自动打开手机屏幕大小界面(Aidex移动端开发项目)

上效果&#xff1a; 下载Aidex的移动端项目并打开&#xff1a; 若依-ruoyi-AiDex-Uniapp: 若依-Ruoyi APP 移动解决方案&#xff0c;基于uniappuView封装的一套基础模版&#xff0c;开箱即用&#xff0c;免费开源&#xff0c;一份代码多终端适配&#xff0c;支持H5、支付宝小程…

阿里云香港轻量应用服务器网络线路cn2?

阿里云香港轻量应用服务器是什么线路&#xff1f;不是cn2。 阿里云香港轻量服务器是cn2吗&#xff1f;香港轻量服务器不是cn2。阿腾云atengyun.com正好有一台阿里云轻量应用服务器&#xff0c;通过mtr traceroute测试了一下&#xff0c;最后一跳是202.97开头的ip&#xff0c;1…

UE蓝图 入口(FunctionEntry)节点和源码

系列文章目录 UE蓝图 Get节点和源码 UE蓝图 Set节点和源码 UE蓝图 Cast节点和源码 UE蓝图 分支(Branch)节点和源码 UE蓝图 入口(FunctionEntry)节点和源码 文章目录 系列文章目录一、FunctionEntry节点功能二、入口节点用法1. 创建函数2. 命名函数3. 定义参数4. 编写函数逻辑5…

喜讯 | 重庆炼石入选重庆市科技局科技型企业

近日&#xff0c;重庆炼石网络技术有限公司&#xff08;以下简称“重庆炼石”&#xff09;经过严格审查&#xff0c;获得由重庆市科学技术局备案、重庆生产力促进中心&#xff08;重庆市科技型企业系统受托管理单位&#xff09;发证的《重庆市科技型企业备案证书》&#xff0c;…

国产洗地机品牌哪个好?热门品牌洗地机推荐

随着人们生活节奏的加快和生活压力的增加&#xff0c;“懒人好物”逐渐成为消费热点。在家庭清洁方面&#xff0c;吸尘器是最早被广泛接受的工具&#xff0c;但随着人们对便捷性和效率的需求增加&#xff0c;家用洗地机和扫地机器人等新型清洁工具开始受到欢迎。这些工具的出现…

入门OpenCV:图像阈值处理

图像阈值是一种简单、高效的图像分割方法&#xff0c;目的是将图像转换成二值图像。这个过程涉及比较像素值和阈值&#xff0c;根据比较结果来确定每个像素点的状态&#xff08;前景或背景&#xff09;。图像阈值在处理二维码、文本识别、物体跟踪等领域中非常有用。本博客旨在…

【图片公式识别】图片公式转Word与LaTeX文档:智能识别与转换

前言 嘿&#xff0c;大家好呀&#xff01;&#x1f44b; 谁都知道&#xff0c;写 Word 文档里的公式可不是一件简单的事情&#xff01;你辛辛苦苦在键盘上敲出的数学公式&#xff0c;结果随着 Word 版本的更新&#xff0c;竟然变成了一张图片&#xff01;&#x1f624; 这简直就…