簡體   English   中英

獲取分段錯誤(代碼轉儲到C ++中)

[英]Getting segmentation error(code dumped in c++

這里遇到什么問題? 我很混亂? 該程序應顯示一副洗牌。

我是編碼新手,所以我不明白...

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

// names of ranks.
static const char *ranks[] ={"Ace, Two, Three, Four, Five, Six, Seven, 
                              Eight, Nine, Ten, Jack, Queen, King"};

// name of suites
static const char *suits[] ={"Spades, Clubs, Diamonds, Hearts"};

void print_card(int n)
{
    cout << ranks[n % 13] << " of " << suits[n / 13] << endl;
}

int main()
{
    srand((unsigned int)time(NULL));

    vector<int> deck;

    // Prime, shuffle, dump
    for (int i=0; i<52; deck[i++]=i)
    {
        for_each(deck.begin(), deck.end(), print_card);
    }
    return 0;
}

我收到一個錯誤(分段),但我不知道它是什么:(

static const char *ranks[] ={"Ace, Two, ..., King"};

這是一個大小的陣列與所述單個元件是整個字符串,這意味着訪問ranks[<anything other than zero>]是未定義的行為。

您需要的是一組不同的字符串,例如:

static const char *ranks[] ={"Ace", "Two", ..., "King"};

同樣適用於suits陣列。


不建議您參考向量中尚不存在的元素,例如,在deck為空時, deck deck[i++]=i

要設置現有元素,可以使用該方法(盡管它不會像vector::at()那樣進行邊界檢查vector::at()所以初學者可能應該使用該方法)。

要將元素附加到向量的后面,可以使用vector::push_back()


但是,如果您要成為C ++編碼器,則應該完全接受該語言包括在用戶定義的類型提供更多保護和表達能力時脫離基本類型。

您可以使用以下內容生成Card類:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

class Card {
public:
    enum Rank { Ace, Two, Three, Four, Five, Six, Seven, Eight,
        Nine, Ten, Jack, Queen, King, EndRank };
    enum Suit { Spades, Clubs, Diamonds, Hearts, EndSuit };

    explicit Card(Rank rank = Ace, Suit suit = Spades)
        : m_rank(rank), m_suit(suit) {}

    std::string ToString() const {
        return m_rankLookup[m_rank] + " of " + m_suitLookup[m_suit];
    }

private:
    const Rank m_rank;
    const Suit m_suit;

    static const std::vector<std::string> m_rankLookup;
    static const std::vector<std::string> m_suitLookup;

    friend std::ostream &operator<<(std::ostream &os, const Card& me) {
        return os << me.ToString();
    }
};

const std::vector<std::string> Card::m_rankLookup { "Ace", "Two", "Three",
    "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack",
    "Queen", "King" };
const std::vector<std::string> Card::m_suitLookup { "Spades", "Clubs",
    "Diamonds", "Hearts" };

然后,您可以使用Deck類在此基礎上構建以下內容:

class Deck {
public:
    explicit Deck(unsigned numDecks = 1) {
        for (unsigned i = 0; i < numDecks; ++i) {
            for (auto suit = Card::Spades;
                suit != Card::EndSuit;
                ++(*reinterpret_cast<int*>(&suit)))
            {
                for (auto rank = Card::Ace;
                    rank != Card::EndRank;
                    ++(*reinterpret_cast<int*>(&rank)))
                {
                    m_deck.push_back(Card(rank, suit));
                }
            }
        }
    }

    std::string ToString() const {
        if (m_deck.size() == 0) {
            return "";
        }
        std::stringstream ss;
        ss << m_deck[0];
        for (unsigned i = 1; i < m_deck.size(); ++i) {
            ss << ", " << m_deck[i];
        }
        return ss.str();
    }

private:
    std::vector<Card> m_deck;

    friend std::ostream &operator<<(std::ostream &os, const Deck& me) {
        return os << me.ToString();
    }
};

從那里開始,只需要根據需要使用類就可以了,因為知道C ++會比使用原始整數更徹底地對事物進行類型檢查。

然后,您只需添加功能即可進行其他任何處理,例如從卡座上隨機取出一張卡片或將其放回原處。

我用於這些類的測試工具是:

int main() {
    Deck deck;
    std::cout << "[" << deck << "]\n";
}

我得到的輸出是(為了可讀性而重新格式化):

[Ace of Spades, Two of Spades, Three of Spades, Four of Spades,
 Five of Spades, Six of Spades, Seven of Spades, Eight of Spades,
 Nine of Spades, Ten of Spades, Jack of Spades, Queen of Spades,
 King of Spades, Ace of Clubs, Two of Clubs, Three of Clubs,
 Four of Clubs, Five of Clubs, Six of Clubs, Seven of Clubs,
 Eight of Clubs, Nine of Clubs, Ten of Clubs, Jack of Clubs,
 Queen of Clubs, King of Clubs, Ace of Diamonds, Two of Diamonds,
 Three of Diamonds, Four of Diamonds, Five of Diamonds,
 Six of Diamonds, Seven of Diamonds, Eight of Diamonds,
 Nine of Diamonds, Ten of Diamonds, Jack of Diamonds,
 Queen of Diamonds, King of Diamonds, Ace of Hearts, Two of Hearts,
 Three of Hearts, Four of Hearts, Five of Hearts, Six of Hearts,
 Seven of Hearts, Eight of Hearts, Nine of Hearts, Ten of Hearts,
 Jack of Hearts, Queen of Hearts, King of Hearts]

當您使用創建deck對象時

vector<int> deck;

它是一個空向量。 在這樣的對象上使用deck[i++]是不正確的。 您可以使用以下方法創建所需大小的對象

vector<int> deck(52);

由於大小是在編譯時已知的,因此最好使用std::array

std::array<int, 52> deck;

發生核心是因為循環時deck [0]為NULL

可以像這樣

    for (int i=0; i<52; i++)
    {
       deck.push_back(i);
    }
    for_each(deck.begin(), deck.end(), print_card);

和字符串arr

    static const char *ranks[] ={"Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"};
    static const char *suits[] ={"Spades", "Clubs", "Diamonds", "Hearts"};

您的卡座沒有任何元素,因此無法以這種方式在其上循環。

vector<int> deck;

// Prime, shuffle, dump
for (int i=0; i<52; deck[i++]=i)
{      
  for_each(deck.begin(), deck.end(), print_card);
}

在聲明后調用resize(52)或直接調用在其中放置52個空元素的構造函數deck(52)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM