C++ 如何使用对和指针在地图中删除和擦除?

C++ 如何使用对和指针在地图中删除和擦除?,c++,c++11,map,C++,C++11,Map,我以这种方式声明了一张地图: static map<string, pair<Socket*,queue<string>*>> panels; panels.insert(make_pair(cdhw, make_pair(&sock, new queue<string>()))); cdhw是用于标识面板的字符串 这是删除和擦除的正确方法吗?在映射和/或对中使用指针是否存在问题?擦除后,我得到一个“分段错误(内核转储)”,但我不知道问

我以这种方式声明了一张地图:

static map<string, pair<Socket*,queue<string>*>> panels;
panels.insert(make_pair(cdhw, make_pair(&sock, new queue<string>())));
cdhw是用于标识面板的字符串


这是删除和擦除的正确方法吗?在映射和/或对中使用指针是否存在问题?擦除后,我得到一个“分段错误(内核转储)”,但我不知道问题是在删除还是其他代码中(可能与多线程相关)。

您确定在调用
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?
}

在映射中使用
static
变量以及堆栈上分配的
Socket*
(自动变量)听起来很可怕。如果您只是移动到动态分配的套接字,那么应该会有所改进。

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

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

sock
已超出范围时,您不会执行任何操作,是吗?首先,不要动态分配队列。这只会带来痛苦。你最好在队列中使用智能指针将指针存储在这样的容器中可能有点危险,特别是如果你的Socket*是一个自动变量。@Antonio:不,直接存储队列就行了。额外的间接层在这里毫无用处。为什么?如果自动作用域适用于
Socket
,则肯定更可取。使用
static
假定他从函数返回并在下次调用时重用该变量,或者使用任何函数作用域之外的变量。在这两种情况下,存储指向自动变量的指针是一种破坏方法,这取决于
套接字的生存期。显然,在生命周期结束后在映射中保留指针不是一个好主意,但这与堆栈上是否分配了
Socket
无关。(在这类事情的通常设计中,
Socket
的构造函数将进行插入,其析构函数将从映射中删除它。类似于
Socket
的东西经常出现在堆栈上。)@JamesKanze:在这种特殊情况下,OP说:“Socket*用作指向自动分配变量的指针”。换句话说,他在堆栈上分配套接字结构。就我而言,这是一个巨大的危险信号。这是服务器中的常见模式;
Socket
具有连接的寿命,每个连接都在一个单独的线程中,并且是该线程中的最低级别函数。
Socket
对象自然是一个局部变量,将使用RAII技术从保存它的任何贴图等中插入和删除。
map<string, pair<Socket *, queue<string>>> panels ;
panels.emplace(cdhw, make_pair(&sock, queue<string>()));
panels.erase( cdhw ) ;