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

个人主页:PingdiGuo_guo

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

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

文章目录

1.动态分配内存的思想

2.动态分配内存的概念

2.1内存分配函数

2.2动态内存的申请和释放

2.3内存碎片问题

3.动态分配内存的作用

[3.1 灵活分配内存空间](#3.1 灵活分配内存空间)

[3.2 提高内存利用率](#3.2 提高内存利用率)

[3.3 动态数据结构的实现](#3.3 动态数据结构的实现)

[3.4 避免内存溢出和内存泄漏](#3.4 避免内存溢出和内存泄漏)

[3.5 提高程序的性能](#3.5 提高程序的性能)

[3.6 总结](#3.6 总结)

4.动态分配内存的实现

[4.1 步骤](#4.1 步骤)

[4.1.1 确定需要分配的内存大小](#4.1.1 确定需要分配的内存大小)

[4.1.2 使用new操作符分配内存](#4.1.2 使用new操作符分配内存)

[4.1.3 检查分配是否成功](#4.1.3 检查分配是否成功)

[4.1.4 使用分配的内存](#4.1.4 使用分配的内存)

[4.2 代码示例](#4.2 代码示例)

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

[5.1 动态分配单个对象的内存](#5.1 动态分配单个对象的内存)

[5.1.1 介绍](#5.1.1 介绍)

[5.1.2 代码示例](#5.1.2 代码示例)

[5.2 动态分配对象数组的内存](#5.2 动态分配对象数组的内存)

[5.2.1 介绍](#5.2.1 介绍)

[5.2.2 代码示例](#5.2.2 代码示例)

[5.3 注意事项](#5.3 注意事项)

6.动态分配内存的练习

[6.1 题目描述](#6.1 题目描述)

[6.2 知识点](#6.2 知识点)

[6.3 步骤](#6.3 步骤)

[6.3.1 初始化](#6.3.1 初始化)

[6.3.2 输入数组大小](#6.3.2 输入数组大小)

[6.3.3 分配内存](#6.3.3 分配内存)

[6.3.4 输入字符串内容](#6.3.4 输入字符串内容)

[6.3.5 显示字符串内容](#6.3.5 显示字符串内容)

[6.3.6 用户选择](#6.3.6 用户选择)

[6.3.7 释放内存](#6.3.7 释放内存)

[6.3.8 结束程序](#6.3.8 结束程序)

[6.4 代码](#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++中动态分配和释放内存:

cpp 复制代码
#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 代码示例

cpp 复制代码
#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 代码示例

cpp 复制代码
#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 代码

cpp 复制代码
#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.总结

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

相关推荐
元亓亓亓24 分钟前
Java后端开发day36--源码解析:HashMap
java·开发语言·数据结构
道剑剑非道28 分钟前
QT 打包安装程序【windeployqt.exe】报错c000007d原因:Conda巨坑
开发语言·qt·conda
小邓儿◑.◑1 小时前
C++武功秘籍 | 入门知识点
开发语言·c++
码银3 小时前
Java 集合:泛型、Set 集合及其实现类详解
java·开发语言
大G哥3 小时前
PHP标签+注释+html混写+变量
android·开发语言·前端·html·php
傻啦嘿哟3 小时前
HTTP代理基础:网络新手的入门指南
开发语言·php
fish_study_csdn3 小时前
pytest 技术总结
开发语言·python·pytest
杨筱毅4 小时前
【优秀三方库研读】【C++基础知识】odygrd/quill -- 折叠表达式
c++·三方库研读
曹牧4 小时前
Java 调用webservice接口输出xml自动转义
java·开发语言·javascript
hjjdebug5 小时前
c++中的enum变量 和 constexpr说明符
c++·enum·constexpr