奇怪的内存行为与字符串数组

时间:2018-01-10 11:09:03

标签: c++ arrays

我需要在个人项目的控制台窗口内打印一个Vigenere广场但是我遇到了打印功能的一些问题,因为它偷偷摸摸其他类中#&# 39;内存并打印出来自它们的字符串。

对于那些不知道什么是Vigenere广场的人来说,这里是picture

这是我的代码:

static void square() {
    string cipher[27];
    cipher[0] = "  | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
    for (int i = 0; i < 26; i++) {
        string tmp = (char)(i + 'A') + " |";
        for (int j = 0; j < 26; j++) {
            tmp += " " + (char)(((j + i) % 26) + 'A');
        }
        cipher[i + 1] = tmp;
    }
    for (int i = 0; i < 27; i++) cout << cipher[i] << endl;
}

我的方法是使用for循环逐个创建每个字符串,该循环增加行的字母ascii值,另一个用于每个颜色移动1的字符。这是奇怪的输出:

Console

我单独运行此代码,但它从我以前用于创建菜单的类中窃取字符串"Invalid Option! Press any key to dismiss." 。我认为它是如何访问保留给该类的部分内存的。 我做错了什么?

3 个答案:

答案 0 :(得分:5)

问题在于这两行:

$starttime

首先评估赋值的右侧,然后才是用于构造string tmp = (char)(i + 'A') + " |"; tmp += " " + (char)(j + i + 'A'); 的结果。字符串文字通常一起存储在程序的某些静态存储器中。在程序中,文字具有指向该存储器的指针的值。单个字符基本上是一个数字。虽然 + plus运算符用于与std::string连接,但它对指针和数字的行为却不同。如果你将std::string添加到char指针(或任何指针),它只是将指针指向另一个地方 - 在你的情况下指向程序的其他字符串。

要打破它:

  • char*假设(char)(i + 'A') + " |"i = 0存储,例如在" |"上:
  • 0xabcd1234
  • (char)(0 + 65) + (char*)0xabcd1234
  • (char)65 + (char*)0xabcd1234 - oops,我们没有构造一个连接字符串,我们创建了指向一些随机内存的指针!

您可以通过多种方式编写程序。最小的变化是:

(char*)0xabcd1275

这意味着 - 确保+运算符的至少一侧实际上是string tmp = (char)(i + 'A') + string(" |"); tmp += string(" ") + (char)(j + i + 'A');

答案 1 :(得分:2)

您的代码中的主要问题是您认为通过将空字符串与char连接将自动变为字符串,这是错误的(这意味着“指向空字符串的某些副本的指针,由数字提前c的值(​​绝对不是你想要的);&gt;&gt;引自此处:C++ convert from 1 char to string?)。

最终代码可能如下所示:

void square() {
    string cipher[27];
    cipher[0] = "  | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
    for (int i = 0; i < 26; i++) {
        string tmp="";
        tmp+=(char)(i + 'A');
        tmp+=" |";
        for (int j = 0; j < 26; j++) {
            tmp += " ";
            tmp+=(char)(j + i + 'A');
        }
        cipher[i + 1] = tmp;
    }
    for (int i = 0; i < 27; i++) cout << cipher[i] << endl;
}

将字符单独添加到字符串中。

答案 2 :(得分:0)

您正在混淆stringchar,这可能不是您的意图。我也假设你使用的是std :: string。

不应使用字符串数组,而应使用char数组或字符串。

例如,

string cipher;