在内存字符串表示形式差异抛出map :: at()中的错误

时间:2016-09-25 20:29:02

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

在字符串填充构造函数创建strRom_map_intAra.at(s)时调用s时遇到范围外异常(请参阅#5 http://www.cplusplus.com/reference/string/string/string/)。

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

这是字符串表示问题还是c = 'I'方法的问题?如果这两个变量都是字符串,为什么它们的实现细节很重要?

map::at()

总结一下:GDB显示// 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" c = 'I' , s{1,c} = "\001I" , test = "I"会导致strRom_map_intAra.at(s)异常,而out-of-range则不会

1 个答案:

答案 0 :(得分:3)

尝试使用

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)使用给定的char(I初始化了所有字符)。

使用

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

使用字符列表对字符串进行初始化:

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

  • 和一个字符'I'