首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >std::std::成对的指针

std::std::成对的指针
EN

Stack Overflow用户
提问于 2014-09-29 16:14:35
回答 2查看 831关注 0票数 1

我正在编写一些简单的连接组件代码,并遇到了一个奇怪的片段错误。

我的代码如下:先给出一些定义。

代码语言:javascript
运行
复制
Node* node;

typedef std::pair<int, Node*> Edge;

struct Node {
    ...
    std::list<Edge> neighbors;
    ...
}

分段错误的代码如下:

代码语言:javascript
运行
复制
if (node->neighbors.empty())
{
    node->label = label_set.make();
}
else
{
    Node* first_neighbor = node->neighbors.front().second;
    node->label = first_neighbor->label;
    int i = 0;
    for (list<Edge>::iterator it = node->neighbors.begin(); it != node->neighbors.end(); it++)
    {   
        i ++;
        Node* n2 = (Node*)it->second;
        node->label = label_set.merge(node->label, n2->label);
    }
}

真正奇怪的一点是以下几点:

代码语言:javascript
运行
复制
(lldb) p node->neighbors
(std::list<std::pair<int, _Node *>, std::allocator<std::pair<int, _Node *> > >) $4 = size=1 {
  [0] = {
    first = 78
    second = 0x00d85520
  }
}
(lldb) p *it
(std::pair<int, _Node *>) $8 = {
  first = 0
  second = 0xa0a45254
}
(lldb) p n2
(Node *) $5 = 0xa0a45254

看到这个,我明白了分段的错误。n2被设置为一个完全奇怪的值。它不在列表中;我是否没有正确地迭代列表?n2是否被随机数据填充,因为它超出了列表的范围?但是,我的迭代是如何摆脱界限的呢?我太笨了。

编辑:,我肯定在列表范围之外:在段错误i == 3时。

EDIT2是否与我跟踪节点的方式有关?

https://gist.github.com/noio/3082a0f351edb1821e90

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-29 17:10:24

以下可能是正在发生的情况:

如果您确实注释掉了调用label_set.merge的for循环中的最后一行,那么只剩下一个简单的循环,这个循环应该从std::list的开头一直到末尾。

增量是存在的(尽管执行++it更好,但这是另一回事),再加上在循环中所做的一切都是检索it->second。然而,正如您所声称的那样,您的循环将永远运行。

由于是这种情况,一个结论是node无效,或者node->neighbors无效。您需要检查您的代码,以确保您没有错误地管理内存或指针。使用智能指针也比使用原始指针更好(甚至可以使用

std::pair<int, std::shared_ptr<Node>>

如果节点指针确实在各个对象之间共享)。

至于调试器,您可以在无效的对象中拥有看起来很好的值。可能发生的情况是,调试器正在向您显示无效对象中各个成员的值。由于对象无效,这些值可以是任何值,包括合理的外观值。

编辑:

你在这里发布的链接:https://gist.github.com/noio/3082a0f351edb1821e90

显示获取vector<Node>中最后一项的地址。这是危险的,如果向量调整到一个更大的容量,因为向量的迭代器将失效。不要持有指向向量内数据的指针值,除非可以保证在使用指针时不会调整矢量的大小。

票数 1
EN

Stack Overflow用户

发布于 2014-09-29 16:45:58

最好的猜测是,对label_set.merge的调用从

node->neighbors列表,使it迭代器无效。当它返回时,您尝试增加迭代器以继续循环,但是由于它已经失效(可能现在指向已释放的内存),它就会进入永不停歇的状态。

由于您没有展示label_set是什么或者merge是如何工作的,所以不可能知道。

另一种可能是,您已经以某种方式破坏了堆,并以任意裁剪要覆盖的内容的方式使指针在周围悬空。尝试使用缬磨运行,看看它是否能告诉您更多的错误。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26104307

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档