vector清空容器的操作以及个人的一些见解

本文探讨了C++中vector的内存管理,包括当vector不再使用时如何主动释放内存。介绍了vector的capacity()和size()的区别,并提供了两种释放内存的方法:使用swap交换为空vector和调用shrink_to_fit。强调了单纯clear()不会释放内存,而shrink_to_fit仅是编译器的建议,实际是否释放取决于编译器实现。最后,建议根据构造函数开销和编译器支持选择合适的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当vector中存入大量的数据后,当我们不再使用vector中的元素后,如果能积极主动的去释放内存,那么是非常明智的。(对于小容量的数据,就没有这个必要了,因为对性能影响甚微)

一、 知识背景:

PS:这一部分是对文章题目所言操作的背景介绍,只关心题目的读者可以跳过

为了支持随机访问,vector将元素连续存储到一块空间上(每个元素紧挨着前一个元素),那么当容器空间满了以后,再次插入新元素的时候,容器必须分配新的内存空间来保存已有元素和新的元素,即将已有元素从旧位置挪到新位置,再添加新元素到新位置。如果当容器满了以后,每添加一个新元素,都要执行一次这样的操作,那么额外的开销未免太大了(拷贝旧元素)。
所以标准库为了减少这种额外的开销,通常在vector容量满了以后,再申请的空间通常是比以前的空间大很多的,不同的平台下具体实现不同(Linux下是2倍,Windows下Visual Stdio是1.5倍),这些额外的空间用来备用,可以用来保存更多的元素。这样,就不需要每次添加新元素都重新分配容器的内存空间了。

capacity() 方法就是返回vector在不重新分配空间的情况下,可以容纳元素的最大值,所以包含哪些也许还没有被使用的空间。而 size() 是返回vector中已保存/有效元素的个数。

二、清空容器并释放内存

第一种:
使用swap。swap的作用是交换两个容器底层的数据结构。如果我们创建一个临时的空vector和需要释放内存的vector交换底层数据结构,就相当于释放了内存。
demo:

#include <iostream>
#include <vector>

int main(){
   
   
	std::vector<int> ve;
	for (std::vector<int>::size_type i = 0; i < 100; ++i){
   
   
		ve.push_back(
#include <iostream> #include <fstream> #include <string> #include <vector> #include <memory> // 用于智能指针 using namespace std; class Information { private: int age; double weight; public: Information() : age(0), weight(0) {} Information(int a, double w) : age(a), weight(w) {} void setAge(int a) { age = a; } void setWeight(double w) { weight = w; } int getAge() const { return age; } double getWeight() const { return weight; } void display() const { cout << "年龄: " << age << " 岁,体重: " << weight << " kg"; } }; class Employee { protected: string id; string name; Information info; double money; public: Employee() : id(""), name(""), money(0) {} Employee(string i, string n, Information inf) : id(i), name(n), info(inf), money(0) {} virtual void pay() = 0; virtual void showType() = 0; void display() { pay(); // 确保在显示前计算工资 cout << "工号: " << id << "\n姓名: " << name << endl; info.display(); cout << "\n月薪: " << money << " 元" << endl; } virtual void writeFile(ofstream& ofs) { pay(); // 确保在写入文件前计算工资 ofs << id << "\n" << name << "\n" << info.getAge() << "\n" << info.getWeight() << "\n" << money << "\n"; } // 添加读取文件的虚函数 virtual void readFile(ifstream& ifs) { getline(ifs, id); getline(ifs, name); int age; double weight; ifs >> age >> weight; ifs.ignore(); // 忽略换行符 info = Information(age, weight); ifs >> money; ifs.ignore(); // 忽略换行符 } virtual ~Employee() {} // 虚析构函数 }; class Technician : public Employee { private: int hour; public: Technician() : hour(0) {} Technician(string i, string n, Information inf, int h) : Employee(i, n, inf), hour(h) {} void setHour(int h) { hour = h; } int getHour() const { return hour; } void pay() override { money = hour * 100; } // 固定时薪100元 void showType() override { cout << "技术类员工"; } void writeFile(ofstream& ofs) override { ofs << "Technician\n"; Employee::writeFile(ofs); ofs << hour << "\n"; } void readFile(ifstream& ifs) override { Employee::readFile(ifs); ifs >> hour; ifs.ignore(); // 忽略换行符 } }; class Manager : virtual public Employee { public: Manager() {} Manager(string i, string n, Information inf) : Employee(i, n, inf) {} void pay() override { money = 8000; } // 固定月薪8000元 void showType() override { cout << "经理类员工"; } void writeFile(ofstream& ofs) override { ofs << "Manager\n"; Employee::writeFile(ofs); } void readFile(ifstream& ifs) override { Employee::readFile(ifs); } }; class Salesman : virtual public Employee { protected: double sales; public: Salesman() : sales(0) {} Salesman(string i, string n, Information inf, double s) : Employee(i, n, inf), sales(s) {} void setSales(double s) { sales = s; } void pay() override { money = sales * 0.04; } // 固定提成比例4% void showType() override { cout << "销售类员工"; } void writeFile(ofstream& ofs) override { ofs << "Salesman\n"; Employee::writeFile(ofs); ofs << sales << "\n"; } void readFile(ifstream& ifs) override { Employee::readFile(ifs); ifs >> sales; ifs.ignore(); // 忽略换行符 } }; class ManagerSales : public Manager, public Salesman { public: ManagerSales() {} ManagerSales(string i, string n, Information inf, double s) : Employee(i, n, inf) { sales = s; } void pay() override { money = 5000 + sales * 0.005; // 固定月薪5000+0.5%提成 } void showType() override { cout << "销售经理类员工"; } void writeFile(ofstream& ofs) override { ofs << "ManagerSales\n"; Employee::writeFile(ofs); ofs << sales << "\n"; } void readFile(ifstream& ifs) override { Employee::readFile(ifs); ifs >> sales; ifs.ignore(); // 忽略换行符 } }; class Info { private: vector<unique_ptr<Employee>> employees; // 使用智能指针管理内存 public: void addEmployee(Employee* emp) { employees.emplace_back(emp); } void showInfo() { for (auto& emp : employees) { emp->showType(); cout << ":\n"; emp->display(); cout << "\n------------------------\n"; } } void writeInfo(const string& filename) { ofstream ofs(filename); if (!ofs) { cerr << "文件打开失败!" << endl; return; } for (auto& emp : employees) { emp->writeFile(ofs); } ofs.close(); cout << "数据已保存到文件!\n"; } // 读取文件信息 void readInfo(const string& filename) { ifstream ifs(filename); if (!ifs) { cerr << "文件打开失败!" << endl; return; } // 清空当前员工列表 employees.clear(); string type; while (getline(ifs, type)) { unique_ptr<Employee> emp; if (type == "Technician") { emp = make_unique<Technician>(); } else if (type == "Manager") { emp = make_unique<Manager>(); } else if (type == "Salesman") { emp = make_unique<Salesman>(); } else if (type == "ManagerSales") { emp = make_unique<ManagerSales>(); } else { cerr << "未知的员工类型: " << type << endl; continue; } emp->readFile(ifs); employees.push_back(move(emp)); } ifs.close(); cout << "数据已从文件加载!\n"; } }; class Menu { private: Info info; public: void showMenu() { cout << "\n===== 工资管理系统 =====\n" << "1. 添加信息\n" << "2. 显示信息\n" << "3. 写入文件\n" << "4. 读取文件\n" << "5. 退出程序\n"; } void handleInput() { int choice; while (true) { showMenu(); cout << "请选择操作(1-5): "; cin >> choice; cin.ignore(); if (choice == 5) break; switch (choice) { case 1: { int type; cout << "请输入员工类型(1技术人员 2销售员 3经理 4销售经理): "; cin >> type; cin.ignore(); string id, name; int age; double weight; cout << "请输入员工编号: "; getline(cin, id); cout << "请输入员工姓名: "; getline(cin, name); cout << "请输入年龄: "; cin >> age; cout << "请输入体重(kg): "; cin >> weight; Information inf(age, weight); switch (type) { case 1: { int hours; cout << "请输入工作时间(小时): "; cin >> hours; info.addEmployee(new Technician(id, name, inf, hours)); cout << "技术人员信息已添加!\n"; break; } case 2: { double sales; cout << "请输入本月销售额(元): "; cin >> sales; info.addEmployee(new Salesman(id, name, inf, sales)); cout << "销售人员信息已添加!\n"; break; } case 3: { info.addEmployee(new Manager(id, name, inf)); cout << "经理信息已添加!\n"; break; } case 4: { double sales; cout << "请输入部门销售额(元): "; cin >> sales; info.addEmployee(new ManagerSales(id, name, inf, sales)); cout << "销售经理信息已添加!\n"; break; } default: cout << "无效的员工类型!\n"; } break; } case 2: if (info.size() == 0) { cout << "没有员工信息,请先添加或读取数据!\n"; } else { info.showInfo(); } break; case 3: info.writeInfo("D:\\information.txt"); break; case 4: info.readInfo("D:\\information.txt"); break; default: cout << "无效的选择,请重新输入!\n"; } } } // 添加获取Info大小的函数用于检查 int size() const { return info.size(); } }; int main() { Menu menu; menu.handleInput(); return 0; }严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息 错误 C2039 "size": 不是 "Info" 的成员 课设 D:\testC++\课设\课设\源.cpp 316
最新发布
06-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值