将本地向量复制到映射中某个键的值时遇到段错误

Posted

技术标签:

【中文标题】将本地向量复制到映射中某个键的值时遇到段错误【英文标题】:Hitting a segfault when copying local vector to the value of a certain key in map 【发布时间】:2017-08-01 16:25:47 【问题描述】:
class TrackSymbol

        protected: static std::map<int, std::vector<char> > _trackTypeToIdentificationCodeMap ;

        protected: static char _identificationCodeChars[][2] ;
 ;

在实现文件中:

std::map<int, std::vector<char> > TrackSymbol::_trackTypeToIdentificationCodeMap ;

char TrackSymbol::_identificationCodeChars[][2] =

     ' ', ' ' ,
     'S', '6' ,
     'Z', 'U' 
 ;

在构造函数中,我试图用 _identificationCodeChars 中的适当值填充本地向量,但在副本中遇到了段错误:

    for ( int i = 0 ; i < sizeof( _identificationCodeChars ) / sizeof( _identificationCodeChars[0] ) ; i++ )
    
        std::vector<char> vec ;
        vec.push_back( _identificationCodeChars[i][0] ) ;
        vec.push_back( _identificationCodeChars[i][1] ) ;

        _trackTypeToIdentificationCodeMap[i] = vec ; //Segfault here
    

我的理解是赋值运算符会对本地向量进行硬拷贝,所以我对它为什么会遇到分段错误感到有些困惑。另外,在我当前的环境中,我仅限于 C98,所以我无法使用扩展初始化列表等内容。

【问题讨论】:

请编辑您的问题以包含minimal reproducible example 【参考方案1】:

静态成员变量基本上是一个花哨的全局变量。特别是该地图的构造函数在该程序的执行中仅被调用一次,而不是为每个 TrackSymbol 对象调用一次。 (但是,它保证在int main()中执行第一行之前运行。)

从你所说的很难判断,但我猜你已经在_trackTypeToIdentificationCodeMap 的构造函数运行之前实例化了一个 TrackSymbol 对象,例如在_trackTypeToIdentificationCodeMap 之前定义的全局变量中或另一个文件。直接的解决方法是移动该定义。更好的解决方法可能是使该成员变量非静态(如果您能承受性能损失)或使用单例函数(在旧 C++ 版本中,这不能保证是线程安全的):

std::map<int, std::vector<char> > getCodeMap_internal()

    static char _identificationCodeChars[][2] =
    
         ' ', ' ' ,
         'S', '6' ,
         'Z', 'U' 
     ;
    std::map<int, std::vector<char> > _trackTypeToIdentificationCodeMap;
    for ( int i = 0 ; i < sizeof( _identificationCodeChars ) / sizeof( _identificationCodeChars[0] ) ; i++ )
    
        std::vector<char> vec ;
        vec.push_back( _identificationCodeChars[i][0] ) ;
        vec.push_back( _identificationCodeChars[i][1] ) ;

        _trackTypeToIdentificationCodeMap[i] = vec ;
    
    return _trackTypeToIdentificationCodeMap;


const std::map<int, std::vector<char> >& getCodeMap()

    static std::map<int, std::vector<char> > _trackTypeToIdentificationCodeMap
        = getCodeMap_internal();
    return _trackTypeToIdentificationCodeMap;

【讨论】:

以上是关于将本地向量复制到映射中某个键的值时遇到段错误的主要内容,如果未能解决你的问题,请参考以下文章

JNI 类 ID 段错误

C ++ 11分段错误试图将数组(<算法>)动态复制到向量中

带有向量作为键的 STL 映射

在多重映射中,当两个迭代器保存具有映射到不同 Value 的相同键的值时。我们如何才能在地图中找到它们中的哪一个在另一个之前

while循环产生的错误,这段代码有啥问题?

解决eclipse导出javadoc时的“错误: 编码GBK的不可映射字符”问题(转)