推回向量时出错访问错误

时间:2015-07-18 03:21:22

标签: c++ xcode

我有这两个类:

posts/show

NSInteger numWidth = 3;
NSInteger numHeight = 10;
CGFloat border = 8;
CGFloat width = (self.scrollView.frame.size.width - (numWidth + 1) * border)/3;

for (NSInteger i = 0; i < numWidth; ++i) {
    for (NSInteger j = 0; j < numHeight; ++j) {
        UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"imageNameHere"]];
        imageView.frame = CGRectMake(border + width*i, border + width*j, width, width);
        [self.scrollView addSubview:imageView];
    }
}
[self.scrollView setContentSize:CGSizeMake(self.scrollView.frame.size.width, (border + width)*numHeight + border];

每当我调用self.detailLabel.text=@"Visit BBC News for up-to-the-minute news, breaking news, video, audio and feature stories. BBC News provides trusted"; self.detailLabel.numberOfLines=0; self.detailLabel.lineBreakMode=NSLineBreakByWordWrapping; [self.detailLabel sizeToFit]; 中的class card { //class that represents a card int cardNumber; //the ID of the card that give it itse level and suit std::vector<std::string> suits = { "hearts", "spades", "diamonds", "clubs" }; std::vector<std::string> levels { "Ace", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"}; std::string suit; std::string level; public: card(int nCardNumber) { //constructor that initiliazes all properties of the card cardNumber = nCardNumber; level = levels[cardNumber%13]; suit = suits[cardNumber/13]; } void printValue() { //prints the cards level and suit using namespace std; cout << level << " of " << suit << endl; } }; 函数时,我都会得到EXC_BAD_ACCESS(代码= 1)。

我通过在class hand { //represents the hand a player is holding int playerNumber; std::vector<card> playerHand; //vector of carsa public: hand(int m_playerNumber) { playerNumber = m_playerNumber; } void addCard(int cardNumber) { //adds a card to the hand card cardToBeAdded(cardNumber); cardToBeAdded.printValue(); playerHand.push_back(cardToBeAdded); } void printHand() { using namespace std; cout << "Player " << playerNumber << " has:" << endl; for (int i = 0; i < 2; i++) { playerHand[i].printValue(); } } }; 中声明两个成员并更改函数来重写这些值而不是向向量添加新值来尝试一些调试,但是相同的错误。

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:0)

通过一些适当的调试,很容易看出发生了什么。我已经将您的示例缩小到最低限度,以便重现您的错误,因为我不相信它与std::vector::push_back有关。

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

class card {                //class that represents a card
int cardNumber;         //the ID of the card that give it itse level and suit
std::vector<std::string> suits = { "hearts", "spades", "diamonds", "clubs" };
std::vector<std::string> levels { "Ace", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};

std::string suit;
std::string level;

public:    
card(int nCardNumber) {     //constructor that initiliazes all properties of the card
    cardNumber = nCardNumber;
    std::cout << cardNumber % 13 << std::endl;
    std::cout << cardNumber / 13 << std::endl;
    level = levels[cardNumber%13];
    suit = suits[cardNumber/13];
}

void printValue() {         //prints the cards level and suit
    using namespace std;
    cout << level << " of " << suit << endl;
}
};

int main() {
    std::vector<card> v;
    for (size_t n = 0; n <= 52; ++n)
    {
        // Replicate "addCard" function
        card c(n);
        c.printValue();
        v.push_back(c);
    }
    return 0;
}

您会在此注意到两件事:我已经为card构造函数添加了一些调试帮助,因为我认为问题是访问std::vector<std::string>和我{&#39}。我试图添加所有52张牌。瞧,前51张卡成功添加;然而,试图添加俱乐部之王有一个错误。让我们看看为什么:

card(int nCardNumber) { // nCardNumber = 52;
    cardNumber = nCardNumber; // 52
    const int nCard = cardNumber % 13; // King
    const int nSuit = cardNumber / 13; // 4
    level = levels[nCard];
    suit = suits[nSuit]; // whoops, out of bounds!
}

您可以在此处看到您正在尝试访问超出范围的suits[4]

答案 1 :(得分:0)

这正确编译并运行&#34;&#34;在Visual Studio 2013社区。好吧,除了VS2013没有成员资格列表,所以我不得不输入那些。我可以获得错误的唯一方法是具有超出显而易见的卡范围的值(> 52,&lt; 0)。这就是你正在做的事情吗?

其他问题:正常的卡片套牌没有“1&#39;卡,从级别向量中删除1。完成后,在main中运行:

for (int i = 0; i < 52; ++i)
    playerHand.addCard(i);

在我的手上,按顺序为所有4件套装吐出所有牌A到K.但是,如果我给它一个超出这些界限的值,它将给出一个错误。

使用vector.at(index)而不是[]运算符从向量中获取值更安全。向量上的[]运算符将其视为原始C数组,因此如果您没有运行某种调试程序来捕获它,如果您将其提供给不适当的值,则它将是未定义的行为。这意味着,如果你很幸运,它会在没有任何解释的情况下崩溃。向量的一个优点是,您可以使用at方法来召唤索引,并使用非常清晰的名称抛出异常。

此外,如果您有一个需要用户输入的功能,并且可以输入错误的数字(就像在这种情况下那样),那么检查输入以确保输入是个好主意这很好。

正如彼得所指出的那样,在课堂上使用矢量来保持标签是不优雅的,浪费了记忆。一个简单的解决方案是制作变量:

static std::vector<std::string suits...

静态关键字意味着,除了你应该仔细研究的其他内容之外,它们只会被创建一次并在所有类的实例中持久存在。

答案 2 :(得分:0)

你可能有一些代码(你没有显示)使用cardNumber作为数组索引,而不是cardNumber % 13或类似的,并且没有数组边界。

如果cardnumber/13为52或更高,则使用cardNumber作为数组索引也会失败。

另外......

suitslevelscard的非静态成员,因此card的每个实例都有自己的这些向量副本。

我不希望每次调用hand::addCard()时都会出现问题但是,如果你的代码创建了很多牌,给他们添加了很多牌,而不是清理 - 那么它就会耗尽可用内存比你想要的更快。

如果您遇到可用内存限制(取决于您的操作系统,可用内存等),那么这可以解释您的问题。