堆叠变量' temp'已经腐败了

时间:2014-07-24 19:36:58

标签: c++ exception stack-corruption

我试图将包含多个以空格分隔的值的std :: string转换为矢量对象。我有它工作(意味着调试器在算法结束时向量中显示正确的值),但是我得到了一个我以前从未见过的例外。例外情况如下:

Exception I am getting.

我以前从未见过这一点,而且我已经研究了一小时关于造成这种情况的原因,我仍然不理解它。

导致异常的算法如下:

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;从某种意义上说,我得到了正确的结果,我只需要清理异常。我该如何解决这个问题?

4 个答案:

答案 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本身无法验证它。虽然一些现代编译器可以检查传递给printfscanf的值是否与格式说明符匹配并生成警告,但这通常不起作用(例如传递给函数的格式,而不是使用字符串文字) 。所以这里sscanf取消引用指针&amp; temp作为指向unsigned int的指针,并覆盖临时变量周围的内存,作为char == 1的sizeof。