【问题标题】:How to delete and erase in a map with a pair and pointers?如何使用一对和指针在地图中删除和擦除?
【发布时间】:2013-11-19 08:37:29
【问题描述】:

我有一张这样声明的地图:

static map<string, pair<Socket*,queue<string>*>> panels;

其中 Socket 是一个用户定义的类,用于封装 Linux 套接字。 Socket* 用作指向自动分配变量的指针,队列是动态分配的。 我以这种方式在地图中插入新元素:

panels.insert(make_pair(cdhw, make_pair(&sock, new queue<string>())));

当我必须删除地图的一个元素时,我会这样做:

delete( (panels.find(cdhw))->second.second ); //delete queue
panels.erase(cdhw);

cdhw 是一个用于识别面板的字符串。

这是删除和擦除的正确方法吗?在地图和/或一对中使用指针是否存在问题?擦除后我收到“分段错误(核心转储)”但我不明白问题是在删除还是其他代码(可能与多线程有关)。

【问题讨论】:

  • sock 已经超出范围时,你不会做任何这些,是吗?
  • 对于初学者,不要动态分配队列。那只会带来痛苦。
  • 你最好为你的队列使用智能指针
  • 在这样的容器中存储指针可能有点冒险,尤其是当您的 Socket* 是一个自动变量时。
  • @Antonio:不,直接存储队列。额外的间接层在这里没有用处。

标签: c++ c++11 map


【解决方案1】:

您确定当您调用find 时,您确定地图中有该元素吗?您可以添加这个,以检查是否找到了元素:

auto It = panels.find(cdhw);
if(It != panels.end())
{
    // The element was found
    delete((It->second.second); //delete queue
    panels.erase(cdhw);
}
else
{
    // The element was not found, is this an error case?
}

【讨论】:

    【解决方案2】:

    为您的地图使用static 变量以及分配在堆栈上的Socket*(自动变量)听起来很可怕。如果您只是转向动态分配的 Sockets,它应该会有所改善。

    【讨论】:

    • 为什么?如果自动作用域适用于Socket,那肯定是更可取的。
    • 使用static 假定他从函数返回并在下次调用时重用该变量,或者使用任何函数范围之外的变量。在这两种情况下,存储指向自动变量的指针都会导致灾难
    • 这取决于Socket 的生命周期。显然,在生命周期结束后将指针留在映射中并不是一个好主意,但这与 Socket 是否在堆栈上分配无关。 (在此类事物的通常设计中,Socket 的构造函数将执行插入操作,而其析构函数会将其从映射中删除。像 Socket 这样的东西在堆栈上的情况非常频繁。)
    • @JamesKanze:在这种特殊情况下,OP 声明:“Socket* 用作指向自动分配变量的指针”。换句话说,他在栈上分配了 Socket 结构。就我而言,这是一个巨大的危险信号。
    • 这是服务器中的常见模式; Socket 有一个连接的生命周期,每个连接都在一个单独的线程中,并且是该线程中的最低级别函数。 Socket 对象自然是一个局部变量,将使用 RAII 技术从任何保存它的地图等中插入和删除。
    【解决方案3】:

    正如其他人所提到的,在 c++11 中,您最好按值使用事物,因为使用移动语义您无需为复制构造函数支付任何开销。所以你会像这样定义你的地图:

    map<string, pair<Socket *, queue<string>>> panels ;
    

    您可以通过以下方式进一步优化您的创作:

    panels.emplace(cdhw, make_pair(&sock, queue<string>()));
    

    那么擦除很简单:

    panels.erase( cdhw ) ;
    

    【讨论】:

      猜你喜欢
      • 2019-12-02
      • 2012-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-01
      • 1970-01-01
      相关资源
      最近更新 更多