【问题标题】:In Memory String Representation difference throwing error in map::at()在内存字符串表示中,map::at() 中的差异抛出错误
【发布时间】:2016-09-25 20:29:01
【问题描述】:

s 由字符串填充构造函数创建时,我在调用strRom_map_intAra.at(s) 时遇到了超出范围的异常(参见#5 http://www.cplusplus.com/reference/string/string/string/)。

当我声明和初始化一个字符串时,它会返回预期值。使用 GDB,我可以看到两种不同方法的值的实现方式似乎不同:s = "\001I" ... test = "I" c = 'I'

这是字符串表示还是map::at() 方法的问题?如果这两个变量都是字符串,为什么它们的实现细节很重要?

// Roman_int.cpp
// Roman Constants
extern const int M = 1000;
extern const int CM = 900;
extern const int D = 500;
extern const int CD = 400;
extern const int C = 100;
extern const int XC = 90;
extern const int L = 50;
extern const int XL = 40;
extern const int X = 10;
extern const int IX = 9;
extern const int V = 5;
extern const int IV = 4;
extern const int I = 1;

extern const unordered_map<string, int> strRom_map_intAra
{
    {"M",M},
    {"CM",CM},
    {"D",D},
    {"CD",CD},
    {"C",C},
    {"XC",XC},
    {"L",L},
    {"XL",XL},
    {"X",X},
    {"IX",IX},
    {"V",V},
    {"IV",IV},
    {"I",I}
};

istream& operator>>(istream& is, Roman_int& r)
{
    // throw exception if stream bad()
    is.exceptions(is.exceptions()|ios_base::badbit);

    string romStr;
    get_contig_str(is,romStr);
    vector<int> intRoms;
    for (char c : romStr)
    {
            string s{1,c};
            string test = "I";
            intRoms.push_back(strRom_map_intAra.at(s));
    }
//...

// GDB Snippit
142             for (char c : romStr)
(gdb)
144                     string s{1,c};
(gdb) print c
$1 = 73 'I'
(gdb) n
145                     string test = "I";
(gdb) print s
$2 = "\001I"
(gdb) n
146                     intRoms.push_back(strRom_map_intAra.at(s));
(gdb) print test
$3 = "I"

回顾一下:GDB 显示 c = 'I' , s{1,c} = "\001I" , test = "I" strRom_map_intAra.at(s) 导致 out-of-range 异常,而 test 不会

【问题讨论】:

    标签: c++ string c++11 memory gdb


    【解决方案1】:

    尝试使用

    string s(1,c);
    

    改为

    string s{1,c};
    

    看下面的程序

    #include <iostream>
    
    int main()
     {
       std::string s1(1, 'I');
       std::string s2{1, 'I'};
    
       std::cout << "size s1: " << s1.size() << std::endl;
       std::cout << "size s2: " << s2.size() << std::endl;
     }
    

    它的输出是

    size s1: 1
    size s2: 2
    

    那是因为

    std::string s1(1, 'I');
    

    如果您使用给定大小(在本例中为 1)初始化字符串并使用给定字符(在本例中为I)初始化所有字符,则调用构造函数。

    std::string s2{1, 'I'};
    

    你用一个字符列表初始化你的字符串:

    • 值为 1 的字符 ('\x01')

    • 还有一个字符'I'

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-26
      • 1970-01-01
      • 2016-06-20
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      相关资源
      最近更新 更多