簡體   English   中英

刪除后指向列表元素的指針

[英]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來管理共享所有權。

一些建議:

  • 默認始終使用std :: vector
  • 如果可以使用C ++ 11,則使用標准的shared_ptr進行共享所有權,否則,請使用boost版本。
  • 盡可能多地使用算法標頭(在這種情況下, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM