Middle
Mida juhtub std::vector elementidega realloc operatsiooni ajal?
sobes.tech AI
Vastus AI-lt
std::vector ne kasutab realloc. Kui konteineri suurus muutub ja see nõuab mälu ümberjaotamist, toimub järgmine:
- Vabastatakse uus mäluala sobiva suurusega.
- Elementidest vanas piirkonnas kopeeritakse või liigub need uude.
- Kui tüübid toetavad liikumise semantikat (
Tkoos korrektselt rakendatud liikumiskonstruktoriga ja/või liikumisega määramise operaatoriga), kasutatakse liikumist. See on tõhusam, kuna vanad ressursid (näiteks mälu, mis on määratud sisemistele objektidele) antakse uutele objektidele, ja vanad objektid jäävad kehtivaks, kuid määratlemata või tühjendatakse destruktoritega. - Kui tüübid ei toeta liikumist või kui kompilaator ei saa liikumist rakendada, kasutatakse koopiat.
- Kui elemendid on triviaalne koopiatav (
Ton POD-tüüp või omab triviaalset koopimise ja liikumise operatsiooni), võib kasutadamemcpyvõi sarnaseid madala taseme funktsioone, et kiiresti kopeerida töötlemata andmeid.
- Kui tüübid toetavad liikumise semantikat (
- Destructors kutsutakse vanade elementide jaoks.
- Vanad mäluressursid vabastatakse.
Oluline on märkida, et vanade elementide pointerid ja viited muutuvad kehtetuks pärast ümberjaotamist.
#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;
}
// Kopeerikonstruktor
MyItem(const MyItem& other) : name(other.name) {
std::cout << "Copying " << name << std::endl;
}
// Kopeerivõtja
MyItem& operator=(const MyItem& other) {
if (this != &other) {
name = other.name;
std::cout << "Copy assigning " << name << std::endl;
}
return *this;
}
// Liikumiskonstruktor
MyItem(MyItem&& other) noexcept : name(std::move(other.name)) {
std::cout << "Moving " << name << std::endl;
}
// Liikumisega määramise operaator
MyItem& operator=(MyItem&& other) noexcept {
if (this != &other) {
name = std::move(other.name);
std::cout << "Move assigning " << name << std::endl;
}
return *this;
}
// Destruktor
~MyItem() {
std::cout << "Destroying " << name << std::endl;
}
};
int main() {
std::vector<MyItem> items;
items.reserve(2); // Vabastame ruumi kahe elemendi jaoks
items.emplace_back("item1"); // Ei toimu ümberjaotust
items.emplace_back("item2"); // Ei toimu ümberjaotust
std::cout << "Kolmanda elemendi lisamine, käivitab realloc-like operatsiooni:" << std::endl;
items.emplace_back("item3"); // Vajalik ümberjaotus
// Väljund näitab liikumist item1 ja item2, siis vanade objektide destruktsiooni
// ja uue item3 konstruktsiooni.
// Kui MyItem ei toetaks liikumist, oleks väljund koopimisest.
return 0;
}