尝试显示对象数组时出现运行时错误

问题描述

所以,我正在尝试用 C++ 创建一个纸牌游戏,在尝试确保我的数组正常工作时,我收到了一个运行时错误内容为:

在 Sabacc.exe 中的 0x7AD940D9 (vcruntime140d.dll) 处抛出异常:0xC0000005:访问冲突写入位置 0x0BFE1052。

我不知道这个错误实际上意味着什么,但这是我的代码,以便您可以看到发生了什么:

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace std;
/* run this program using the console pauser or add your own getch,system("pause") or input loop */

class cards {
public:
    string suit;
    int number = 0;
};

int main(int argc,char** argv) {
    /*Initialise Arrays*/
    cards Card[60];

    //initialise Vars
    string suits[4] = { "Coins","Flasks","Sabers","Staves" };
    int values[15] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };

    //Define Card Values
    for (int c = 1; c < 61; c++) {

        if (c >= 1 && c <= 15) {
            Card[c].suit = "Coins";
            Card[c].number = c;
        }
        else if (c >= 16 && c <= 30) {
            Card[c].suit = "Flasks";
            Card[c].number = c - 15;
        }
        else if (c >= 31 && c <= 45) {
            Card[c].suit = "Sabers";
            Card[c].number = c - 30;
        }
        else if (c >= 46 && c <= 61) {
            Card[c].suit = "Staves";
            Card[c].number = c - 45;
        }

    }

    for (int i = 1; i < 60; i++) {
        cout << Card[i].number << " " << Card[i].suit << endl;
    }

    return 0;
}

如果你能帮忙,那就太好了。我是一个完整的初学者,所以我可能遗漏了一个非常明显的答案。

解决方法

    for (int c = 1; c < 61; c++) {

off-by-one error 在这里。数组 cards Card[60]; 只有 60 个元素(Card[0]Card[59]),因此您不得访问 Card[60]

由于您在循环中仅使用 Card[1]Card[59] 进行打印,因此您应该根据此调整您的第一个循环。

换句话说,条件 c < 61 应该更改为 c < 60

另一种选择是将 cards Card[60]; 更改为 cards Card[61];(再添加一个元素)并(可选)将第二个循环的条件 i < 60 更改为 i < 61

Card[0] 未使用,但我认为在现代 PC 上浪费几个字节中的一个元素是可以的,这些 PC 有足够的内存通过从 1 开始索引来提高可读性和/或简单性。

,

cards 结构分配索引 0-59。在第一次迭代中,循环没问题,但为了更好地理解,我做了一些修改。您可以了解正在分配哪些索引。在打印语句中,如果您不想显示“0”,则可以从 1 开始循环。主要是错误在第 25 行 for (int c = 1; c < 61; c++) {

看看下面的完整代码:

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

using namespace std;
/* run this program using the console pauser or add your own getch,system("pause") or 
input loop */

class cards {
public:
  string suit;
  int number = 0;
 };

int main(int argc,char** argv) {
 /*Initialise Arrays*/
 cards Card[60]; //indexes 0-59 gets allocated

 //initialise Vars
string suits[4] = { "Coins","Flasks","Sabers","Staves" };
int values[15] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };

//Define Card Values
for (int c = 0; c < 60; c++) { //iterate 0-59 i.e 60 elements

    if (c >= 1 && c <= 15) {
        Card[c].suit = "Coins";
        Card[c].number = c;
    }
    else if (c >= 16 && c <= 30) {
        Card[c].suit = "Flasks";
        Card[c].number = c - 15;
    }
    else if (c >= 31 && c <= 45) {
        Card[c].suit = "Sabers";
        Card[c].number = c - 30;
    }
    else if (c >= 46 && c <= 61) {
        Card[c].suit = "Staves";
        Card[c].number = c - 45;
    }

}

for (int i = 0; i < 60; i++) { //prints 0-59 i.e 60 elements
    cout << Card[i].number << " " << Card[i].suit << endl;
}
return 0;

}