繁体   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