字符串长度导致访问冲突值 -Visual Studio C++

Posted

技术标签:

【中文标题】字符串长度导致访问冲突值 -Visual Studio C++【英文标题】:String length causes access violation values -Visual Studio C++ 【发布时间】:2017-05-17 22:52:50 【问题描述】:

在我谈论这个问题之前,让我解释一下什么不起作用:

1) 尝试不返回任何值并制作函数void 2) 对尝试的指针进行了大量更改array[i]*(array+i) 我不会得到错误的唯一方法是将string 变量的存储更改为简单的cout<<。当i=25 或换句话说array[] 超过 25 时会出现错误。

string kelime_uret(int dizi[], int length) 
    string kelime;
    for (int i = 0; i < length; i++) 

        if (dizi[i] == 1)  kelime[i] = 'A'; 
        else if (dizi[i] == 2)  kelime[i] = 'B'; 
        else if (dizi[i] == 3)  kelime[i] = 'C'; 
        else if (dizi[i] == 4)  kelime[i] = char(128); 
        else if (dizi[i] == 5)  kelime[i] = 'D'; 
        else if (dizi[i] == 6)  kelime[i] = 'E'; 
        else if (dizi[i] == 7)  kelime[i] = 'F'; 
        else if (dizi[i] == 8)  kelime[i] = 'G'; 
        else if (dizi[i] == 9)  kelime[i] = char(166); 
        else if (dizi[i] == 10)  kelime[i] = 'H'; 
        else if (dizi[i] == 11)  kelime[i] = 'I'; 
        else if (dizi[i] == 12)  kelime[i] = char(152); 
        else if (dizi[i] == 13)  kelime[i] = 'J'; 
        else if (dizi[i] == 14)  kelime[i] = 'K'; 
        else if (dizi[i] == 15)  kelime[i] = 'L'; 
        else if (dizi[i] == 16)  kelime[i] = 'M'; 
        else if (dizi[i] == 17)  kelime[i] = 'N'; 
        else if (dizi[i] == 18)  kelime[i] = 'O'; 
        else if (dizi[i] == 19)  kelime[i] = char(153); 
        else if (dizi[i] == 20)  kelime[i] = 'P'; 
        else if (dizi[i] == 21)  kelime[i] = 'R'; 
        else if (dizi[i] == 22)  kelime[i] = 'S'; 
        else if (dizi[i] == 23)  kelime[i] = char(158); 
        else if (dizi[i] == 24)  kelime[i] = 'T'; 
        else if (dizi[i] == 25)  kelime[i] = 'U'; 
        else if (dizi[i] == 26)  kelime[i] = char(154); 
        else if (dizi[i] == 27)  kelime[i] = 'V'; 
        else if (dizi[i] == 28)  kelime[i] = 'Y'; 
        else if (dizi[i] == 29)  kelime[i] = 'Z'; 
        else if (dizi[i] == 30)  kelime[i] = ' '; 
        else if (dizi[i] == 31)  kelime[i] = ','; 
        else if (dizi[i] == 32)  kelime[i] = '.'; 
        else if (dizi[i] == 33)  kelime[i] = '!'; 
        else if (dizi[i] == 34)  kelime[i] = '?'; 
        else if (dizi[i] == 35)  kelime[i] = '-'; 
        else if (dizi[i] == 36)  kelime[i] = ';'; 
        else if (dizi[i] == 37)  kelime[i] = ':'; 
        else if (dizi[i] == 38)  kelime[i] = '1'; 
        else if (dizi[i] == 39)  kelime[i] = '2'; 
        else if (dizi[i] == 40)  kelime[i] = '3'; 
        else if (dizi[i] == 41)  kelime[i] = '4'; 
        else if (dizi[i] == 42)  kelime[i] = '5'; 
        else if (dizi[i] == 43)  kelime[i] = '6'; 
        else if (dizi[i] == 44)  kelime[i] = '7'; 
        else if (dizi[i] == 45)  kelime[i] = '8'; 
        else if (dizi[i] == 46)  kelime[i] = '9'; 
        else if (dizi[i] == 47)  kelime[i] = '0'; 
        else cout << "ERROR" << endl;
    //i value 25 error dizi[i] 42 >>>> 0x00007FF7B02B150E noktasında, Affin.exe üzerinde özel durum oluştu: 0xC0000005: 0xFFFFFFFFFFFFFFFF konumuna okuma erişimi ihlali.

    return kelime;

这是我打电话的方式:

cout << kelime_uret(dizi, encrypted.size());

附注 笛子 -> 数组, kelime -> 单词 数组的集合成员数与encrypted中的字符数相同。

【问题讨论】:

diziencrypted 之间的神奇关系是什么,所以我们知道数组到底有多大? @John3136 它们的长度完全相同。 encrypted 包含字母,dizi 仅包含数字。 dizi中的数字数量与加密中char的数量相同。 【参考方案1】:

在访问kelime[i] 之前,您没有为kelime 分配任何内存。

在进入循环之前添加对kelime.resize()的调用(循环本身可以大大简化),例如:

static const char letters[] = "ABC\x80""DEFG\xA6HI\x98JKLMNO\x99PRS\x9ETU\x9AVYZ ,.!?-;:1234567890";

string kelime_uret(int dizi[], int length)

    string kelime;
    int value;

    kelime.resize(length);

    for (int i = 0; i < length; ++i)
    
        value = dizi[i];
        if ((value >= 1) && (value <= 47)) 
            kelime[i] = letters[value-1];
        
        else 
            cout << "ERROR" << endl;
        
    

    return kelime;

或者,您可以省略resize()(但请考虑至少使用reserve()),然后使用kelime.push_back(...)kelime += ... 而不是kelime[i],例如:

static const char letters[] = "ABC\x80""DEFG\xA6HI\x98JKLMNO\x99PRS\x9ETU\x9AVYZ ,.!?-;:1234567890";

string kelime_uret(int dizi[], int length)

    string kelime;
    int value;

    kelime.reserve(length);

    for (int i = 0; i < length; ++i)
    
        value = dizi[i];
        if ((value >= 1) && (value <= 47)) 
            kelime += letters[value-1];
        
        else 
            kelime += '\0';
            cout << "ERROR" << endl;
        
    

    return kelime;

或者,使用std::ostringstream 代替std::string,例如:

static const char letters[] = "ABC\x80""DEFG\xA6HI\x98JKLMNO\x99PRS\x9ETU\x9AVYZ ,.!?-;:1234567890";

string kelime_uret(int dizi[], int length)

    ostringstream kelime;
    int value;

    for (int i = 0; i < length; ++i)
    
        value = dizi[i];
        if ((value >= 1) && (value <= 47)) 
            kelime << letters[value-1];
        
        else 
            kelime << '\0';
            cout << "ERROR" << endl;
        
    

    return kelime.str();

【讨论】:

@GiorgiGvimradze:是的【参考方案2】:
string kelime; 

使大小为零std::string。这意味着任何

kelime[i]

将越界并调用Undefined Behaviour。在那之后,没有人知道程序中会发生什么。

size the string ahead of time with std::string::resize 如果你知道长度(看起来你知道),或者使用许多方法中的任何一种来添加字符串,包括:std::string::push_back、+= 运算符和std::string::append。或者,切换到std::stringstream

【讨论】:

以上是关于字符串长度导致访问冲突值 -Visual Studio C++的主要内容,如果未能解决你的问题,请参考以下文章

新/删除导致访问冲突

为啥 *(int*)0=0 不会导致访问冲突?

语法错误或访问冲突:1071 指定的密钥太长;最大密钥长度为 767 字节 [重复]

还有一封信导致 imread 中的访问冲突

理解StringTable

取消引用已删除的指针总是会导致访问冲突?