我有一个存储对象的列表。
list<MyObject> l;
我还有一个方法返回指向其中一个对象的指针(如果存在),否则返回nullp。
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()中返回一些特殊类型的指针,那么如果我在一个元素上调用erase并且该元素仍然被引用,那么它的内存将不会被释放直到指向它的指针超出范围。
我考虑使用引用,但是我需要在get上返回nullptr的可能性,所以我可以从调用者检查返回是否确实是一个有效的对象。
有人可以建议更好的方法来避免这些内存问题吗?
答案 0 :(得分:2)
根据建议您应该使用一些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;
}
答案 1 :(得分:1)
在使用智能指针之前,您可能需要确保能够说明为什么您不能(或不想)设计一个系统,在该系统中您的对象在给定时间只有一个所有者。
智能指针将避免无效的数据访问,但它们有各种或多或少的隐藏问题
std::
容器基本上就像用任何类型的指针填充它们一样无用(指针向量不是对象的向量),例如,让一个线程决定删除对象,而另一个线程从同一存储中抓取一些而没有任何同步是非常危险的。有点好像一个线程认为该对象无效而另一个认为它有效 不会让我觉得这是最强大的设计,但你肯定有自己的理由。
我认为您可以先使用unique_ptr
来查看是否符合您的需求,而不是立即跳转到shared_ptr
。