[英]Pointer to list element after removal
我有一個存儲對象的列表。
list<MyObject> l;
我還有一個方法可以返回指向這些對象之一的指針(如果存在),否則返回nullptr。
MyObject* get(int x) {
for (std::list<MyObject>::iterator it = l.begin(); it != l.end(); ++it) {
if (it->X == x) {
return &(*it);
}
}
return nullptr;
}
如果我get()一個指向元素的指針,並且在我使用它時,它從另一個線程中刪除,則該指針變為無效,並且發生了奇怪的事情:)
我想知道的是,是否有一種方法可以在get()中返回某種特殊類型的指針,以便如果我在某個元素上調用擦除並且該元素仍在被引用,則直到指針被釋放時,它的內存才會釋放超出范圍。
我考慮過使用引用,但是我需要在get上返回nullptr的可能性,因此我可以從調用方檢查返回是否確實是有效對象。
有人可以建議一種更好的方法來避免這些內存問題嗎?
根據建議,您應該使用一些smart_pointer來管理共享所有權。
一些建議:
find_if
是正確的標頭)。 您還應該嘗試使用算法搜索特定元素。 這是一些示例代碼:
#include <algorithm>
#include <iostream>
#include <vector>
#include <memory>
struct MyObject {
int X;
MyObject(int x_value) : X(x_value) {}
};
using element_t = std::shared_ptr<MyObject>;
std::vector<element_t> l{
std::make_shared<MyObject>(3), std::make_shared<MyObject>(4),
std::make_shared<MyObject>(5), std::make_shared<MyObject>(6),
std::make_shared<MyObject>(7), std::make_shared<MyObject>(8)};
element_t get(int x) {
auto it = std::find_if(std::begin(l), std::end(l),
[x](const element_t& elem) { return elem->X == x; });
element_t found;
if (it != std::end(l)) {
found = *it;
}
return found;
}
int main() {
auto f1 = get(6);
if (f1) {
std::cout << "encontrado " << f1->X << std::endl;
} else {
std::cout << "6 no se encontro" << std::endl;
}
auto f2 = get(10);
if (f2) {
std::cout << "encontrado " << f2->X << std::endl;
} else {
std::cout << "10 no se encontro" << std::endl;
}
return 0;
}
在使用智能指針之前,您可能需要確保能夠闡明無法(或不希望)設計一個系統的系統,在該系統中,對象在給定時間只有一個所有者。
智能指針將避免無效的數據訪問,但是它們或多或少都有各種各樣的隱藏問題
std::
容器基本上變得無濟於事,就像用任何一種指針填充它們一樣(指針的向量不是對象的向量), 例如,讓一個線程決定刪除對象,而另一個線程從同一存儲中獲取對象而沒有任何同步,這確實非常危險。 有點像一個線程認為該對象無效,而另一個線程認為該對象有效。
並不是讓我成為最強大的設計,但是您肯定有自己的理由。
我認為您可以從使用unique_ptr
開始,看看是否滿足您的需求,而不是立即跳轉到shared_ptr
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.