C++ C+上的Seg故障+;地图访问

C++ C+上的Seg故障+;地图访问,c++,map,C++,Map,我在正在编写的一些代码中遇到了一个奇怪的问题。基本上是这样的,每当我试图从一张空地图上获取一些信息时,程序就会出错。以下是相关代码: (请注意,struct Pair是前面定义的数据结构,sendMasks是一个良好的std::map) 在我的循环之前,它一点也不出错 现在,如果我在for循环之前进行以下测试,它将出现故障: if( sendMasks->empty() ) 以及任何其他试图确定地图是否为空的尝试 仅当映射为空时才会发生此问题。我对这个问题的唯一想法是,因为我在一个单独的

我在正在编写的一些代码中遇到了一个奇怪的问题。基本上是这样的,每当我试图从一张空地图上获取一些信息时,程序就会出错。以下是相关代码: (请注意,struct Pair是前面定义的数据结构,sendMasks是一个良好的std::map)

在我的循环之前,它一点也不出错

现在,如果我在for循环之前进行以下测试,它将出现故障:

if( sendMasks->empty() )
以及任何其他试图确定地图是否为空的尝试

仅当映射为空时才会发生此问题。我对这个问题的唯一想法是,因为我在一个单独的线程中更新sendMasks,所以它可能没有被正确更新;然而,这没有任何意义,因为这只会发生在映射为空的情况下,并且这段代码以前工作得非常好。对可能发生的事情还有其他想法吗

编辑: 我知道问题出在哪里了

在代码的前面部分,我创建了一个新的char*数组,并将该指针放入另一个长度为4的数组中。然后,我在新数组的末尾添加了一个空字符,但意外地只在第一个数组的末尾添加了一个下标,而这个下标偏离了数组的末尾并重写了一个指针。不知何故,这种方法偶尔也能正常工作。(valgrind未检测到此问题)

顺序是这样的:

object* = NULL;  //(overwritten memory)
object->method();

//Inside object::method() : 
map->size(); //segfault.  Gets an offset of 0x24 into the object, 
             //which is NULL to begin with.  memory location 0x24 = invalid

我并不期望对象本身的实例为空,因为在Java中,这个方法调用会在它调用之前失败,而在C中,这将以完全不同的方式完成(我在C++中不做太多面向对象的编程)

如果您从不同的线程访问数据结构,那么必须进行某种同步。您应该确保对象不会同时从不同线程访问。同样,您应该确保其中一个线程所做的更改对其他线程完全可见

A(如果在Windows上)应该可以做到这一点:每次访问都应该锁定结构。这确保了对数据结构的独占访问,并为您设置了所需的内存屏障

欢迎来到多线程世界

或者:

  • 你在某处犯了一个错误,破坏了你的记忆。通过valgrind运行您的应用程序以找出位置

  • 您没有在访问线程之间共享的对象时使用锁。你绝对必须这样做


  • 我知道指向地图的指针很好;我能行

    it = sendMasks->begin();
    it = sendMasks->end();
    
    在我的循环之前,它一点也不出错

    这种逻辑是有缺陷的

    分段错误不是某种一致、可靠的错误指示。它们只是完全不可预测的系统的一个可能的症状,当您调用未定义的行为时就会出现

    这段代码以前工作得非常好

    这一点在这里也适用。它可能已经默默地“工作”了多年,悄悄地覆盖了内存中它可能安全访问或可能没有安全访问的字节


    仅当映射为空时才会发生此问题

    幸运的是,当地图为空时,你的bug是显而易见的。纯属偶然。

    两件简单的事情:1)在单独的线程中更新地图,如果操作不正确,可能会导致许多不同的问题;2)你确定地图是好的吗?begin()和end()可能会成功,即使映射不好:这可能是一个骗局。
    object* = NULL;  //(overwritten memory)
    object->method();
    
    //Inside object::method() : 
    map->size(); //segfault.  Gets an offset of 0x24 into the object, 
                 //which is NULL to begin with.  memory location 0x24 = invalid
    
    it = sendMasks->begin();
    it = sendMasks->end();