這個代碼片段很好地總結了我的問題:
struct T {
int* heapValue;
T(){
this->heapValue = new int[3]; // any dynamic size
}
~T(){
delete[] this->heapValue;
}
}
int main() {
int N = 5; // some value determined at runtime
T* array = new T[N];
for (int i = 0; i < N; i )
{
T t = T(123, 456, args);
t.do_something();
array[i] = t;
} // uh oh, t is deconstructed! and array[i].heapValue is invalidated
int x = array[0].heapValue[0]; // segfault
}
我能夠通過創建來解決這個問題,T** array并讓每個twith new T(args),但是當array需要釋放時,我需要回圈遍歷每個元素并在洗掉陣列本身之前先洗掉它。這是緩慢且不方便的。此外,T**看起來像一個可能會產生誤導的二維陣列。
同樣的問題發生std::vector<T>在同樣緩慢和不方便的std::vector<T*>.
有沒有辦法創建一個動態陣列T*,使得元素在分配后不會立即解構?
uj5u.com熱心網友回復:
您問題下的評論已經總結了處理此問題的所有可能性。無論如何,這里是如何使用移動語意的快速示例,對您的代碼進行最少的更改:
struct T {
int* heapValue;
T(){
std::cout << "CTOR: " << this << std::endl;
this->heapValue = new int[3]; // any dynamic size
}
~T(){
std::cout << "DTOR: " << this << std::endl;
delete[] this->heapValue;
}
T(const T& other) = delete;
T& operator=(const T& other) = delete;
T& operator=(T&& other)
{ // this can be more simple if you decide to use std::unique_ptr to hold your heapValue
delete[] this->heapValue;
this->heapValue = other.heapValue;
other.heapValue = nullptr;
return *this;
}
T(T&& other)
{
*this = std::move(other); // to avoid duplicate code
}
void do_something(){
std::cout << "do_something: " << this << std::endl;
heapValue[0]= 123; // just for demonstration
heapValue[1]= 456;
heapValue[2]= 789;
}
};
int main() {
int N = 5; // some value determined at runtime
T* array = new T[N];
for (int i = 0; i < N; i )
{
T t = T();
t.do_something();
array[i] = std::move(t);
}
std::cout << array[0].heapValue[0] << std::endl;
std::cout << array[0].heapValue[1] << std::endl;
std::cout << array[0].heapValue[2] << std::endl;
}
通過洗掉復制建構式和賦值,我們確保不會有無效的記憶體訪問。通過提供移動分配,我們可以用一種廉價的方式將物件存盤在陣列中。
uj5u.com熱心網友回復:
在這一行
T t = T(123, 456, args);
您正在創建一個區域變數,該變數很快超出范圍,因此您嘗試使用的指標無效,請嘗試在回圈中分配 new
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/339988.html
標籤:C
下一篇:使用c 提取資料并存盤在txt中
