【问题标题】:Segmentation Fault (C++)分段错误 (C++)
【发布时间】:2013-10-12 19:47:03
【问题描述】:

到目前为止,我的代码旨在创建一副牌,每个套件的值为 9 - ACE,并向 4 位玩家发 5 张牌。这些牌是发牌3-2-3-2,然后是2-3-2-3,所以每个玩家总共有5张牌。稍后我将编写代码来洗牌,然后在 euchre 游戏中比较它们,但现在我只想发牌。无论如何,它并不完全有效,我愿意接受建议。我得到的错误是“分段错误: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;
}

【问题讨论】:

  • 您是否意识到您的P1,P2,P3,P4 的行范围为0-4?如果是,5-19ifs 是怎么回事?

标签: c++ arrays multidimensional-array segmentation-fault out-of-memory


【解决方案1】:

让我“教你钓鱼”:

调试器会准确地告诉您故障在哪里。如果您使用的是 IDE(Xcode、Eclipse、VS),它有一个很好的接口,您应该使用它。如果没有:

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

这将为您提供确切的位置(哪个函数在哪个行号上)。

【讨论】:

    【解决方案2】:

    你有这样的数组

    char P1[5][25];
    

    但在您的代码中,您正在为 i 索引大于 5 的元素分配值。您必须限制索引以分配给有效且在范围内的元素。仅将 P1[i][j] 的值分配给介于 0 和 4 之间的 i 和介于 0 和 24 之间的 j 才有效。如果您偏离此值,您将面临分段错误的风险,因为您不应该分配给超出数组范围。

    【讨论】:

      【解决方案3】:
       if((i > 4) && (i < 8)) // 5 - 7 // 3 cards
        {
          P3[i][j] = DECK[i][j];
      

      您正在分配给不存在的 P3[5]...P3[6]...P3[7]...。稍后您将对更大的索引执行相同的操作。你必须使用 i=[0,4] j=[0,24]

      【讨论】:

        【解决方案4】:

        请允许我换个角度“教你钓鱼”。

        您的代码使用了两个常数,24 和 25。我很难阅读您的代码,因为您似乎出于不同的目的两次使用了 25。

        不要使用原始常数,而是给它们起有意义的名字。这将帮助您记录您的代码,但也将帮助您避免愚蠢的错误。您可以通过三种方式做到这一点。

        C风格:

        #define NUM_CARDS_IN_DECK 24
        

        优点:在此之后,无论您在何处编写“NUM_CARDS_IN_DECK”,编译器都会看到常量“24”并进行适当的类型转换。缺点:在调试器中你无法判断值的来源。

        枚举:

        enum { NumCardsInDeck = 24 };
        

        优点:出现在某些调试器中,缺点:有时您可能需要强制转换。

        枚举:

        static const size_t NumCardsInDeck = 24;
        

        优点:强类型,一般出现在调试器中,强类型,缺点:强类型。

        但让我们看看这如何改变您的代码:

        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++)
        

        在这里,我们遇到了可能是错误的地方。你在这里使用了数字 25,我怀疑你不是故意的。

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

        那是你打算写的吗?您将根据外部循环的值复制每个单独的字符,我?该代码看起来不起作用,因为您的代码说

        0

        但是你对 P1 的定义说

        0

        5 明显小于 25,所以你将溢出 P1 的第一个索引,对于 P2 等也是如此。

        猜测一下,“P”代表玩家,5 是手的大小。看起来您实际上是在将整个卡牌名称从套牌复制到手上。您可以通过使用“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];
                }
                ...
        

        好的 - 我们在这方面取得了进展,但你仍然会遇到问题,让我们通过使用一些更恒定的名称来简化这一点,并将玩家变成一个单一的实体。并将其修剪成一个可运行的单一阶段。

        #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;
        }
        

        您可以在此处看到此代码运行:http://ideone.com/8MUOCt

        【讨论】:

          猜你喜欢
          • 2017-08-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多