【问题标题】:String Array Causes C++ Program to Crash字符串数组导致 C++ 程序崩溃
【发布时间】:2015-11-03 02:24:35
【问题描述】:

我正在为我的编程课编写一个多功能程序,其中一个函数需要使用字符串数组。

目标是将 10 个名字存储在一个数组中,然后让用户输入一个随机确定“获胜”名字的数字。

唯一的问题是,一旦我执行我的代码,程序在完成 10 个循环以获取名称后崩溃。这是我试图确定的主要问题,是导致崩溃的原因。

整个程序要大很多,但相关代码如下所示。

string Name1, Name2, Name3, Name4, Name5, Name6, Name7, Name8, Name9,     Name10, tempName, winName;

string array[10] = {Name1, Name2, Name3, Name4, Name5, Name6, Name7, Name8, Name9, Name10};

int tempNum = 0;
int winNum;
int userEntry;
int userSelection;

for (int test = 0; test < 11; test++)
{
    cout << "Enter a name: ";
    cin >> tempName;

    array[tempNum] = tempName;
    tempNum++;
}

//The program crashes at this exact spot, right after collecting the 10th name

cout << endl;
cout << "Now choose a random number between 1 and 100: ";
cin >> userEntry;

winNum = static_cast<int>(userEntry * 3.14159 + 12.7 * 10) % 10;

winName = array[winNum];

cout << endl;
cout << "The winner of the game is" << winName << "!" << endl;

【问题讨论】:

  • 您在使用调试器逐行执行程序时观察到了什么?
  • 在你收集第十个名字之后,你试图收集第十一个名字,你注意到了吗?
  • 取消引用 array[10] 超出了有效范围!
  • @PolarisInParis 调试器还意味着您在单步执行代码时必须密切关注代码。您应该已经看到您正在尝试写信给array[10]。这超出了范围。
  • 抱歉,我把运行时调试器误认为是启动编译器。将来我一定会牢记这一点。

标签: c++ arrays string crash


【解决方案1】:

在 for 循环中,您尝试访问 array[10],但它不存在,因为数组只有 10 个元素,从 0 到 9。这就是您的程序崩溃的原因。

将 for 循环中的条件从 for (int test = 0; test &lt; 11; test++) 更改为 for (int test = 0; test &lt; 10; test++),它应该可以工作。

【讨论】:

  • 哈哈,答案是一个微不足道的数学错误,我既有点尴尬又松了一口气。将其切换回 10 可以修复程序,并且它现在可以完美运行。谢谢!
【解决方案2】:

您的数组有 10 个元素,并且您正在访问 11 个元素,从 0 到 10,这会导致您的程序崩溃。因为您的代码正在访问不属于您的程序的位置。将 for 循环中的条件从 test &lt; 11 更改为 test &lt; 10。 如果可以,请使用string 类的“at”函数,当您尝试访问超出范围的下标时,它会引发异常。

【讨论】:

    【解决方案3】:

    两个问题。

    第一,您正在实例化一个包含 10 个元素的数组,然后查找它的第 11 个元素。 首先,将 if 条件从 test

    其次,您的程序可能会因大量输入而崩溃。 初始化字符串数组时,编译器会为数组分配一定的内存。

    分配给数组的内存量由编译器决定。 编译器确定每个字符串变量的大小,并将其乘以 10 得到数组所需的总大小,并相应地分配那么多内存。

    虽然字符串可以动态调整大小,但数组不能。该数组分配有固定数量的内存。

    因此,如果在输入通过覆盖其索引保存到数组中的字符串期间,您可能会在数组中写入比它可以容纳的字符更多的字符。

    将分配的内存量取决于实现,因为字符串的默认容量取决于实现。

    一个简单的解决方法是将名称字符串定义为开头的大字符串,例如 string Name1 = "------------------------- ";

    这样用户输入的大小很可能小于初始值。

    【讨论】:

    • 我很欣赏详细的解释。不幸的是,即使将所有名称值都设置为 = " ",程序仍然在同一个位置崩溃。我会考虑将编码方法从数组中更改出来,但赋值指令特别要求在那里使用数组。
    • 您的“简单解决方法”如何解决超出数组末尾的访问问题?提示:它没有
    • 另外,你的意思是迭代 10 次而不是 11 次?将 test
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多