简体   繁体   English

分段错误(C ++)

[英]Segmentation Fault (C++)

My code so far is intended to create a deck of cards, values 9 - ACE of each suite, and deal 5 cards to 4 players. 到目前为止,我的代码旨在创建一副纸牌,每个套件的值为9 - ACE ,并向4位玩家分配5张纸牌。 The cards are deal 3-2-3-2 and then 2-3-2-3 so each player has 5 total cards. 发牌是3-2-3-2 ,然后是2-3-2-3因此每个玩家总共有5张牌。 Later on I will write code to shuffle the cards and then compare them in a game of euchre, but for now I just want to deal the cards. 稍后,我将编写代码来洗牌,然后在euchre游戏中将它们进行比较,但是现在我只想处理这些牌。 Anyway it doesn't exactly work and I'am open for suggestion. 无论如何,它并不完全有效,我愿意征求意见。 The Error I get is "Segmentation fault: 11" 我得到的错误是“细分错误:11”

#include <iostream>
#include <fstream>
#include <cstring>
#include <string>

using namespace std;

int cards[24]; //array filled with card values
char DECK[24][25] = 
{ //array filled with card names. Used for dealing //24elements long //25 characters in    each element
"Ace of Spades", "Nine of Spades", "Ten of Spades", "Jack of Spades", "Queen of Spades", "King of Spades",

"Ace of Hearts", "Nine of Hearts", "Ten of Hearts", "Jack of Hearts", "Queen of Hearts", "King of Hearts",

"Ace of Clubs", "Nine of Clubs", "Ten of Clubs", "Jack of Clubs", "Queen of Clubs", "King of Clubs",

"Ace of Diamonds", "Nine of Diamonds", "Ten of Diamonds", "Jack of Diamonds", "Queen of Diamonds", "King of Diamonds" 
};

int main (void)
{
char P1[5][25];
char P2[5][25];
char P3[5][25];
char P4[5][25];

for( int i = 0 ; i < 24 ; ++i) // for the total amount of cards
{
  for(int j = 0; j < 25; j++)
  {
      //1st deal 3-2-3-2
      if(i < 3) // 0 - 2 // 3 cards
      {
        P1[i][j] = DECK[i][j];
      }
  if((i > 2) && (i < 5))// 3 - 4 // 2 cards
  {
    P2[i][j] = DECK[i][j];
  }
  if((i > 4) && (i < 8)) // 5 - 7 // 3 cards
  {
    P3[i][j] = DECK[i][j];
  }
  if((i > 7) && (i < 10))// 8 - 9 // 2 cards
  {
    P4[i][j] = DECK[i][j];
  }
  //2nd deal 2-3-2-3
  if((i > 9) && (i < 12)) // 10 - 11 // 2 cards
  {
    P1[i][j] = DECK[i][j];
  }
  if((i > 11) && (i < 15))// 12 - 14 // 3 cards
  {
    P2[i][j] = DECK[i][j];
  }
  if((i > 14) && (i < 17)) // 15 - 16 // 2 cards
  {
    P3[i][j] = DECK[i][j];
  }
  if((i > 16) && (i < 20))// 17 - 19 // 3 cards
  {
    P4[i][j] = DECK[i][j];
  }
  }
}

for(int q = 0; q < 5; ++q)
{
  cout << "P1 has the card " << P1[q]<< endl;
}
for(int q = 0; q < 5; ++q)
{
  cout << "P2 has the card " << P2[q]<< endl;
}
//for(int q = 0; q < 5; ++q)
{
  //cout << "P3 has the card " << P3[q]<< endl;
}
//for(int q = 0; q < 5; ++q)
{
 //cout << "P4 has the card " << P4[q]<< endl;
}

return 0;
}

Let me "teach you to fish": 让我“教你钓鱼”:

A debugger will tell you exactly where the fault is. 调试器会告诉您确切的故障位置。 If you're using an IDE (Xcode, Eclipse, VS) it has a nice interface to one and you should use that. 如果您使用的是IDE(Xcode,Eclipse,VS),则它有一个不错的接口,您应该使用它。 If not: 如果不:

$ gdb my_executable
...
> run
...
Segmentation fault
> where

This will give you the exact location (which function on which line number). 这将为您提供确切的位置(哪个功能在哪个行号上)。

You have arrays like this 你有这样的数组

char P1[5][25];

and yet in your code you are assigning values to elements where the i index is larger than 5. You must limit your indices to assign to elements that are valid and in range. 但是在您的代码中,您正在为i索引大于5的元素分配值。您必须限制索引才能分配给有效且在范围内的元素。 It is only valid to assign to values of P1[i][j] for i between 0 and 4 and j between 0 and 24. If you deviate from this you run risk of segmentation fault as you should not be assigning to memory locations that are outside the array bounds. 这是唯一有效的分配到的值P1[i][j]i介于0和4 j如果从这个偏离介于0和24运行段故障的风险,因为你不应该分配给内存位置在数组范围之外。

 if((i > 4) && (i < 8)) // 5 - 7 // 3 cards
  {
    P3[i][j] = DECK[i][j];

you are assigning to P3[5]... P3[6]... P3[7]...which don't exist. 您正在分配给P3 [5] ... P3 [6] ... P3 [7] ...不存在。 Later you are doing the same with even bigger indexes. 后来您对更大的索引执行相同的操作。 You must use i=[0,4] j=[0,24] 您必须使用i = [0,4] j = [0,24]

Allow me to also "teach you to fish" on a slightly different angle. 也请允许我以稍微不同的角度“教您钓鱼”。

Your code uses two constant numbers, 24 and 25. I had a hard time reading your code because you appear to use 25 twice for different purposes. 您的代码使用两个常数,即24和25。我很难读取您的代码,因为您出于不同的目的似乎两次使用25。

Instead of using raw constant numbers, give them meaningful names. 不要使用原始常数,而应给它们有意义的名称。 This will help you to document your code but will also help you to avoid silly mistakes. 这将帮助您记录代码,但也可以避免愚蠢的错误。 There are three ways you can do this. 您可以通过三种方式执行此操作。

C style: C风格:

#define NUM_CARDS_IN_DECK 24

Pros: Wherever you write 'NUM_CARDS_IN_DECK' after this, the compiler will see the constant "24" and do appropriate type conversion. 优点:在此之后的任何地方写入“ NUM_CARDS_IN_DECK”,编译器都将看到常量“ 24”并进行适当的类型转换。 Cons: You can't tell where the value came from in a debugger. 缺点:您无法确定该值来自调试器。

Enum: 枚举:

enum { NumCardsInDeck = 24 };

Pros: Appears in some debuggers, Cons: Sometimes you may have to cast. 优点:出现在某些调试器中,缺点:有时可能需要强制转换。

Enum: 枚举:

static const size_t NumCardsInDeck = 24;

Pros: Strongly typed, generally appears in debuggers, Strongly typed, Cons: Strongly typed. 优点:强类型,通常出现在调试器中,强类型,缺点:强类型。

But lets look at how this changes your code: 但是,让我们看一下这如何更改您的代码:

static const size_t NumCardsInDeck = 24;
static const size_t MaxCardNameLength = 25;

int cards[NumCardsInDeck];
char DECK[NumCardsInDeck][MaxCardNameLength] =
{
    "Ace of Spades", "Nine of Spades", "Ten of Spades", "Jack of Spades", "Queen of Spades", "King of Spades",
    "Ace of Hearts", "Nine of Hearts", "Ten of Hearts", "Jack of Hearts", "Queen of Hearts", "King of Hearts",
    "Ace of Clubs", "Nine of Clubs", "Ten of Clubs", "Jack of Clubs", "Queen of Clubs", "King of Clubs",
    "Ace of Diamonds", "Nine of Diamonds", "Ten of Diamonds", "Jack of Diamonds", "Queen of Diamonds", "King of Diamonds" 
};

int main()
{
    char P1[5][MaxCardNameLength];
    char P2[5][MaxCardNameLength];
    char P3[5][MaxCardNameLength];
    char P4[5][MaxCardNameLength];

    for(size_t i = 0 ; i < NumCardsInDeck; ++i) // for the total amount of cards
    {
        for(int j = 0; j < 25; j++)

Here we come across what is likely to be the bug. 在这里,我们遇到了可能是错误的地方。 You've used the number 25 here and I suspect you didn't mean to. 您在这里使用了数字25,但我怀疑您不是故意的。

        for(size_t j = 0; j < MaxCardNameLength; j++)

Is that what you intended to write? 那是你打算写的吗? You're going to copy each individual character based on the value of the outer loop, i? 您将基于外循环的值复制每个单独的字符,是吗? The code doesn't look like it will work because your code says 该代码看起来不起作用,因为您的代码说

0 <= i < NumCardsInDeck where NumCardsInDeck goes to 25 0 <= i <NumCardsInDeck,其中NumCardsInDeck达到25

but your definition of P1 says 但是您对P1的定义是

0 <= index P1 < 5 0 <=索引P1 <5

5 is clearly smaller than 25, so you are going to overflow the first index of P1, same for P2 etc. 5明显小于25,因此您将溢出P1的第一个索引,与P2相同,依此类推。

At a guess, "P" is for player and 5 is the size of a hand. 猜测中,“ P”代表玩家,而5代表一手牌的大小。 It looks like you are actually copying the entire card name from the deck into the hand. 看来您实际上是在将整个卡片名称从卡组复制到手中。 You can simplify this by using a "const char*" to point to the names: 您可以使用“ const char *”指向名称来简化此操作:

static const size_t NumCardsInDeck = 24;
static const size_t NumCardsPerHand = 5;

int cards[NumCardsInDeck];
const char* DECK[NumCardsInDeck] =
{
    "Ace of Spades", "Nine of Spades", "Ten of Spades", "Jack of Spades", "Queen of Spades", "King of Spades",
    "Ace of Hearts", "Nine of Hearts", "Ten of Hearts", "Jack of Hearts", "Queen of Hearts", "King of Hearts",
    "Ace of Clubs", "Nine of Clubs", "Ten of Clubs", "Jack of Clubs", "Queen of Clubs", "King of Clubs",
    "Ace of Diamonds", "Nine of Diamonds", "Ten of Diamonds", "Jack of Diamonds", "Queen of Diamonds", "King of Diamonds" 
};

int main()
{
    const char* P1[NumCardsPerHand];
    const char* P2[NumCardsPerHand];
    const char* P3[NumCardsPerHand];
    const char* P4[NumCardsPerHand];

    for(size_t i = 0 ; i < NumCardsInDeck; ++i) // for the total amount of cards
    {
        if(i < 3)
        {
            P1[0] = DECK[i];
        }
        else if(i < 6)  // it's an else, so i > 2 is already implied.
        {
            P1[1] = DECK[i];
        }
        ...

Ok - we're making progress here, but you're still going to run into a problem, let's simplify this by using some more constant names and make the players into a single entity. 好的-我们在这里取得了进展,但是您仍然会遇到问题,让我们通过使用一些更常量的名称来简化此过程,并使玩家成为一个实体。 And trim this into a single, runnable stage. 并将其修剪为一个可运行的阶段。

#include <iostream>

static const size_t NumCardsInDeck = 24;
static const size_t NumCardsPerHand = 5;
static const size_t NumPlayers = 4;

// removed 'cards' because we aren't using it.
const char* DECK[NumCardsInDeck] =
{
    "Ace of Spades", "Nine of Spades", "Ten of Spades", "Jack of Spades", "Queen of Spades", "King of Spades",
    "Ace of Hearts", "Nine of Hearts", "Ten of Hearts", "Jack of Hearts", "Queen of Hearts", "King of Hearts",
    "Ace of Clubs", "Nine of Clubs", "Ten of Clubs", "Jack of Clubs", "Queen of Clubs", "King of Clubs",
    "Ace of Diamonds", "Nine of Diamonds", "Ten of Diamonds", "Jack of Diamonds", "Queen of Diamonds", "King of Diamonds" 
};

int main()
{
    const char* hands[NumPlayers][NumCardsPerHand];
    enum { Player1, Player2, Player3, Player4 }; // For indexing the hands.

    std::cout << "We have " << NumPlayers << " hands of " << NumCardsPerHand << " cards." << std::endl;
    std::cout << "Total cards that will be dealt: " << NumPlayers * NumCardsPerHand << std::endl;

    for(size_t i = 0 ; i < NumCardsInDeck; ++i) // for the total amount of cards
    {
        if(i < 3)
        {
            hands[Player1][0] = DECK[i];
        }
        else if(i < 6)  // it's an else, so i > 2 is already implied.
        {
            hands[Player2][0] = DECK[i];
        }
        else
        {
            break;
        }
    }

    std::cout << "hands[0][0] = " << hands[0][0] << std::endl;
    std::cout << "hands[1][0] = " << hands[1][0] << std::endl;

    return 0;
}

You can see this code running here: http://ideone.com/8MUOCt 您可以看到此代码在此处运行: http : //ideone.com/8MUOCt

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM