我试图将包含多个以空格分隔的值的std :: string转换为矢量对象。我有它工作(意味着调试器在算法结束时向量中显示正确的值),但是我得到了一个我以前从未见过的例外。例外情况如下:
我以前从未见过这一点,而且我已经研究了一小时关于造成这种情况的原因,我仍然不理解它。
导致异常的算法如下:
vector<BYTE> ConvertStringOfValuesToVectorOfBytes(std::string valStr)
{
vector<string> vectorOfValues = split(valStr, ' '); //split string into vector of strings (works)
vector<BYTE> Hex;
vector<const char*> vectOfCStrings;
for(int i = 0; i < vectorOfValues.size(); i++)
{
const char* temp = vectorOfValues[i].c_str();
vectOfCStrings.push_back(temp);
}
//now we have a vector of c strings...
for(int i = 0; i < vectOfCStrings.size(); i++)
{
char temp = 0;
sscanf(vectOfCStrings[i], "%x", &temp);
Hex.push_back(temp);
}
return Hex;
} //<-- debugger gets to here and on the next step causes the exception
我不知道如何解决这个问题。正如我所说,算法&#34;工作&#34;从某种意义上说,我得到了正确的结果,我只需要清理异常。我该如何解决这个问题?
答案 0 :(得分:3)
这条线不对:
sscanf(vectOfCStrings[i], "%x", &temp);
格式%x
旨在用于int
,而不是char
。
您遇到堆栈损坏,因为sscanf
需要int
的地址。它会尝试使用您传递的地址作为能够持有int
的地址。它显然使用的内存多于有效内存。
您需要的是:
for(int i = 0; i < vectOfCStrings.size(); i++)
{
int temp = 0;
sscanf(vectOfCStrings[i], "%x", &temp);
Hex.push_back(static_cast<char>(temp));
}
答案 1 :(得分:0)
你的算法到底想要完成什么?
从它的外观来看,你是将std :: string分解为'words'的std :: vector,然后将这些单词转换成c风格的字符串(为什么?),然后组装一个std:vector包含每个单词的第一个字母被解释为int。请改用std:stringstream:
for ( auto& word : vectorOfValues )
{
for ( auto& letter : word )
{
unsigned int val;
std::stringstream ss;
ss << std::hex << word[0];
ss >> val;
Hex.push_back( static_cast<BYTE>( val ) );
}
}
通常,如果您没有直接与C API接口,则不应在c ++中使用c风格的字符串。
答案 2 :(得分:0)
std::vector<unsigned char> func(std::string valStr) {
vector<string> vectorOfValues = split(valStr); //split string into vector of strings (works)
vector<BYTE> Hex;
vector<const char*> vectOfCStrings;
for(int i = 0; i < vectorOfValues.size(); i++) {
const char* temp = vectorOfValues[i].c_str();
vectOfCStrings.push_back(temp);
}
//now we have a vector of c strings...
for(int i = 0; i < vectOfCStrings.size(); i++) {
int temp = 0;
sscanf(vectOfCStrings[i], "%x", &temp);
Hex.push_back(char(temp));
}
return Hex;
}
所以是的,我只是将第二个tmp
设为int,因为sscanf
和类似的东西使用int
作为类型,并且因为byte
小于int,导致你的溢出。
不确定它是否有效,但它不再给我错误。
答案 3 :(得分:0)
罪魁祸首似乎是在这两行中:
char temp = 0;
sscanf(vectOfCStrings[i], "%x", &temp);
这就是为什么printf / scanf系列函数不在C ++中使用并被std::iostream
机制取代的原因。函数sscanf
期望在指定%x
时获取指向unsigned int的指针,但是将指针传递给char,并且sscanf
本身无法验证它。虽然一些现代编译器可以检查传递给printf
或scanf
的值是否与格式说明符匹配并生成警告,但这通常不起作用(例如传递给函数的格式,而不是使用字符串文字) 。所以这里sscanf
取消引用指针&amp; temp作为指向unsigned int
的指针,并覆盖临时变量周围的内存,作为char == 1的sizeof。