C++动态内存管理:new与delete详解及应用场景
C++中的动态内存管理允许程序在运行时根据需要分配和回收堆内存。核心机制依赖于new和delete运算符:new不仅开辟存储空间,还可调用构造函数初始化;delete则在释放内存前自动调用析构函数。掌握这两者的正确用法是编写健壮C++程序的基础。
结果或目标
理解如何在C++中动态创建基本类型和类的实例,学会使用指针操纵内存,并确保在不使用时彻底释放资源,避免内存泄漏。
准备条件
- C++编译器环境(如GCC、Clang或MSVC)。
- 了解基本的类定义、构造函数、析构函数及指针语法。
真实操作顺序
第1步:基本类型的动态分配与释放
目的:演示最基础的new和delete用法,区分单元素与数组的处理差异。
代码示例:
#include <iostream>
using namespace std;
int main()
{
int *p; // 定义指向int型变量的指针
p = new int(3); // 开辟整数空间并初始化为3
cout << *p << endl;
char *p_c;
p_c = new char[10]; // 开辟包含10个元素的字符数组
for(int i=0; i<10; i++)
*(p_c+i) = '0' + i; // 填入字符
for(int i=0; i<10; i++)
cout << *(p_c+i);
delete [] p_c; // 释放数组空间,注意[]关键字
cout << endl;
delete p; // 释放单个对象
return 0;
}
完成状态:new int返回单对象地址,用delete p释放;new char[10]返回数组首地址,必须用delete [] p_c释放,否则引发未定义行为。
第2步:类对象的动态建立与初始化
目的:展示在堆上创建类对象,并在创建同时传入参数初始化,以及如何通过指针访问成员。
操作说明:
- 定义类结构:包含数据成员和构造/析构函数。
- 动态实例化:使用
Box *pt = new Box(12, 15, 18);语法。括号内的参数将传递给构造函数。 - 访问对象:由于对象没有名字,必须通过指针
pt使用箭头运算符>访问成员,如pt->width。
关键代码片段:
Box *pt = new Box(12, 15, 18); // 动态建立并初始化
释放内存:
delete pt; // 触发~Box()析构函数,随后释放内存
第3步:构建动态数据结构(学生信息链表)
目的:结合实际需求,使用动态分配构建单向链表,处理不确定数量的输入,并实现完整的遍历与清理。
业务逻辑:
- 输入处理:先获取学生人数
n,再循环创建n个Student对象。 - 链表组装:
Student类中包含next指针。新节点node通过p->next = node接入链表尾部,p始终指向当前最后一个节点。 - 显示数据:从头节点
head开始,沿next指针遍历直至空指针,调用show()打印信息。
完整实现参考:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Student {
public:
Student(int num, string nam, float e, float m);
void show();
Student * next;
private:
int number;
string name;
float English;
float Math;
};
// ... (构造函数实现省略) ...
int main() {
int n;
cout << "请输入同学人数:";
cin >> n;
Student * head = NULL;
Student * p = NULL;
string name;
float english, math;
for(int i = 1; i <= n; i++) {
cout << "请输入第" << i << "个同学的信息...";
cin >> name >> english >> math;
Student * node = new Student(i, name, english, math);
if(head == NULL)
head = node;
else
p->next = node;
p = node;
if(i == n)
p->next = NULL;
}
// 遍历输出
p = head;
while(p != NULL) {
p->show();
p = p->next;
}
// ========== 释放对象占用的空间 ==========
// 注意:不能直接用头指针遍历释放,需保留原始头指针或使用临时指针
p = head;
while(p != NULL) {
Student * l = p; // 暂存当前节点
p = p->next; // 移动到下一个
delete l; // 释放当前节点
}
return 0;
}
完成判断
成功运行上述代码后,应能根据输入的学生数量动态生成对应数量的对象,正确打印学号、姓名及成绩,且在程序退出前无内存泄漏警告(可使用Valgrind等工具验证)。特别注意链表释放部分的逻辑,必须先保存next指针再释放当前节点,否则会导致后续节点无法访问。
简要总结
动态内存管理是C++的核心特性之一。new负责在堆区分配内存并调用构造函数,delete负责调用析构函数并回收内存。对于数组对象,务必使用带[]的delete形式。在处理链表等动态结构时,维护好指针关系并有序释放内存是防止“悬垂指针”和“内存泄漏”的关键。以上就是C++对象的动态建立与释放的详细内容,更多关于C++内存管理的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









