Middle
Kas notiek ar std::vector elementiem realloc operācijas laikā?
sobes.tech AI
Atbilde no AI
std::vector ne izmanto realloc. Kad mainās konteineru izmērs, kas prasa atmiņas pārdali, notiek šādas darbības:
- Tiek piešķirta jauna atmiņas zona ar pietiekamu izmēru.
- Elementi no vecās zonas tiek pārvietoti uz jauno.
- Ja tipi atbalsta pārvietošanas semantiku (
Tar pareizi realizētu pārvietošanas konstruktoru un/vai pārvietošanas piešķiršanas operatoru), tiek izmantota pārvietošana. Tas ir efektīvāk, jo vecie resursi (piemēram, atmiņa, kas piešķirta iekšējiem objektiem) tiek nodoti jaunajiem objektiem, bet vecie objekti paliek derīgi, bet nenoteiktā stāvoklī vai tiek iztīrīti ar destruktoru. - Ja tipi nepārstāv pārvietošanu vai ja kompilators nevar piemērot pārvietošanu, tiek izmantota kopēšana.
- Ja elementi ir trivāli kopējami (
Tir POD tips vai tam ir trivālas kopēšanas un pārvietošanas operācijas), var tikt izmantotamemcpyvai līdzīgas zema līmeņa funkcijas, lai ātri nokopētu neapstrādātus datus.
- Ja tipi atbalsta pārvietošanas semantiku (
- Tiek izsaukti destruktori vecās zonas elementiem.
- Vecā zona tiek atbrīvota.
Svarīgi atzīmēt, ka norādītāji un atsauces uz vecās zonas elementiem kļūst nederīgas pēc pārdales.
#include <vector>
#include <iostream>
#include <string>
struct MyItem {
std::string name;
// Konstruktor
MyItem(const std::string& n) : name(n) {
std::cout << "Constructing " << name << std::endl;
}
// Kopēšanas konstruktors
MyItem(const MyItem& other) : name(other.name) {
std::cout << "Copying " << name << std::endl;
}
// Kopēšanas operators
MyItem& operator=(const MyItem& other) {
if (this != &other) {
name = other.name;
std::cout << "Copy assigning " << name << std::endl;
}
return *this;
}
// Pārvietošanas konstruktors
MyItem(MyItem&& other) noexcept : name(std::move(other.name)) {
std::cout << "Moving " << name << std::endl;
}
// Pārvietošanas operators
MyItem& operator=(MyItem&& other) noexcept {
if (this != &other) {
name = std::move(other.name);
std::cout << "Move assigning " << name << std::endl;
}
return *this;
}
// Destruktors
~MyItem() {
std::cout << "Destroying " << name << std::endl;
}
};
int main() {
std::vector<MyItem> items;
items.reserve(2); // Rezervē vietu 2 elementiem
items.emplace_back("item1"); // Nav pārdale
items.emplace_back("item2"); // Nav pārdale
std::cout << "Pievienojot trešo elementu, tiek aktivizēta realloc-like operācija:" << std::endl;
items.emplace_back("item3"); // Ir nepieciešama pārdale
// Izvade parādīs pārvietošanu item1 un item2, pēc tam veco objektu destrukciju
// un jauno item3 konstrukciju.
// Ja MyItem nepārstāv pārvietošanu, tiks parādīta kopēšana.
return 0;
}
Tādējādi notiek elementu pārvietošana vai kopēšana uz jauno zonu, pēc tam to destrukcija vecajā zonā.