- C++
C++ 结构体动态结构体 动态内存分配学习笔记
- 2025-8-10 14:15:27 @
C++ 结构体动态结构体 动态内存分配学习笔记
1. 结构体基础回顾
结构体(struct)是 C++ 中一种用户自定义的数据类型,允许将不同类型的数据项组合在一起。
// 定义一个简单的结构体
struct Student {
char name[50]; // 姓名
int age; // 年龄
float score; // 分数
};
2. 结构体的动态内存分配
动态内存分配允许程序在运行时根据需要分配和释放内存,这对于处理不确定数量的数据非常有用。
2.1 单个结构体实例的动态分配
使用 new
运算符为单个结构体实例分配内存:
#include <iostream>
#include <cstring>
struct Student {
char name[50];
int age;
float score;
};
int main() {
// 动态分配一个Student结构体
Student* studentPtr = new Student;
// 访问结构体成员(使用->运算符)
strcpy(studentPtr->name, "张三");
studentPtr->age = 20;
studentPtr->score = 95.5;
// 输出信息
std::cout << "姓名: " << studentPtr->name << std::endl;
std::cout << "年龄: " << studentPtr->age << std::endl;
std::cout << "分数: " << studentPtr->score << std::endl;
// 释放动态分配的内存
delete studentPtr;
studentPtr = nullptr; // 避免悬空指针
return 0;
}
2.2 结构体数组的动态分配
使用 new[]
为结构体数组分配内存:
#include <iostream>
#include <cstring>
struct Student {
char name[50];
int age;
float score;
};
int main() {
int n;
std::cout << "请输入学生数量: ";
std::cin >> n;
// 动态分配结构体数组
Student* students = new Student[n];
// 为每个学生赋值
for (int i = 0; i < n; i++) {
std::cout << "请输入第" << i+1 << "个学生的信息:" << std::endl;
std::cout << "姓名: ";
std::cin >> students[i].name;
std::cout << "年龄: ";
std::cin >> students[i].age;
std::cout << "分数: ";
std::cin >> students[i].score;
}
// 输出所有学生信息
std::cout << "\n所有学生信息:" << std::endl;
for (int i = 0; i < n; i++) {
std::cout << "学生" << i+1 << ":" << std::endl;
std::cout << " 姓名: " << students[i].name << std::endl;
std::cout << " 年龄: " << students[i].age << std::endl;
std::cout << " 分数: " << students[i].score << std::endl;
}
// 释放数组内存
delete[] students;
students = nullptr; // 避免悬空指针
return 0;
}
3. 结构体中包含指针成员的情况
当结构体包含指针成员时,需要特别注意动态内存管理,避免内存泄漏。
4. 动态结构体的浅拷贝与深拷贝
当结构体包含指针成员时,简单的赋值操作会导致浅拷贝问题:
// 浅拷贝问题示例
Student* s1 = new Student;
s1->setName("赵六");
Student* s2 = new Student;
*s2 = *s1; // 浅拷贝:只复制指针值,不复制指向的内容
delete s1; // 释放s1的name内存
// 此时s2->name成为悬空指针,访问它会导致未定义行为
解决方法是实现深拷贝:
// 在Student结构体中添加深拷贝函数
void deepCopy(const Student& other) {
setName(other.name); // 使用已有的setName进行深拷贝
age = other.age;
score = other.score;
}
// 使用方式
Student* s1 = new Student;
s1->setName("赵六");
Student* s2 = new Student;
s2->deepCopy(*s1); // 深拷贝
delete s1; // 安全释放
// s2仍然可以正常使用
5. 常见错误与最佳实践
-
内存泄漏:忘记使用
delete
或delete[]
释放动态分配的内存 -
悬空指针:使用已被释放的内存指针
-
重复释放:对同一块内存释放多次
-
最佳实践:
- 始终配对使用
new
与delete
,new[]
与delete[]
- 释放内存后将指针设置为
nullptr
- 结构体包含指针成员时,实现适当的拷贝和析构函数
- 考虑使用智能指针(如
std::unique_ptr
、std::shared_ptr
)管理动态内存
- 始终配对使用
6. 智能指针与结构体
C++11 引入的智能指针可以自动管理内存,减少内存泄漏风险:
#include <memory> // 包含智能指针头文件
// 使用unique_ptr管理结构体
std::unique_ptr<Student> student = std::make_unique<Student>();
student->setName("孙七");
// 使用unique_ptr管理结构体数组
std::unique_ptr<Student[]> studentArray = std::make_unique<Student[]>(5);
智能指针会在超出作用域时自动释放所管理的内存,大大简化了动态内存管理。
通过以上内容,你应该已经掌握了 C++ 结构体动态内存分配的基本概念和使用方法。实践中要特别注意内存管理,避免常见的内存相关错误。
0 条评论
目前还没有评论...