C ++地图访问上的段错误

时间:2011-07-13 19:38:47

标签: c++ map

我在一些我正在研究的代码中遇到了一个奇怪的问题。基本上发生的事情是,每当我试图从空地图中获取一些信息时,程序会出现段错误。这是相关的代码: (请注意,struct Pair是一个先前定义的数据结构,sendMasks是一个很好的std :: map)

std::map<std::string*, struct Pair*>::iterator it;
for(it = sendMasks->begin(); it != sendMasks->end(); it++){ //segfault
   //(some code goes here)
}

我知道指向地图的指针很好;我能做到

it = sendMasks->begin();
it = sendMasks->end();

在我的循环之前,它根本不会出现段错误。

现在,如果我在for循环之前进行了以下测试,那么它将是段错误的:

if( sendMasks->empty() )

与确定地图是否为空的任何其他尝试一样。

只有在地图为空时才会出现此问题。我对这个问题的唯一想法是,因为我在一个单独的线程中更新sendMasks,它可能没有正确更新;然而,这没有任何意义,因为这只会在地图为空时发生,并且此代码在此之前已完美地运行。关于可能发生什么的任何其他想法?

修改 我弄清楚问题是什么。

在我的代码的早期部分,我正在创建一个新的char *数组并将该指针放入另一个长度为4的数组中。然后我在我的新数组的末尾添加了一个NULL字符,但是偶然只做了一个第一个数组的下标 - 从数组的末尾开始并覆盖指针。不知何故,这成功地偶尔正常工作。 (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

我没想到对象本身的实例是null,因为在Java中,这个方法调用在它甚至做到之前就会失败,而在C中,这将完全不同(我没有做太多的对象 - C ++中的面向编程)

2 个答案:

答案 0 :(得分:2)

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

mutex(或critical section如果在Windows上)应该可以解决这个问题:每次访问都应该锁定结构。这确保了对数据结构的独占访问,并为您提供所需的内存屏障。

欢迎来到多线程世界!

答案 1 :(得分:2)

或者:

  1. 你在某个地方犯了一个错误,并且破坏了你的记忆。通过 valgrind 运行您的应用程序以找出位置。

  2. 您没有使用 locks 来访问您在线程之间共享的对象。你绝对必须这样做。


  3.   

    我知道指向地图的指针很好;我能做到

    it = sendMasks->begin();
    it = sendMasks->end();
    
         

    在我的循环之前,它根本不会出现段错误。

    这种逻辑是有缺陷的。

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

      

    此代码在此之前已经完美无缺

    这同样适用。它可能一直默默地“工作”,悄悄地覆盖内存中可能有或没有安全访问权限的字节。


      

    只有在地图为空时才会出现此问题。

    你很幸运,当地图为空时,你的错误很明显。纯粹的机会。