0

So basically I'm making a short version of Monoply. And I need to make a vector of a struct to contain all the info for multiple players that the user enters that also contains the properties owned by each player. I have a function to create x amount of players and all assign each player with the starting cash. However, when I compile this code, I get the error libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: vector. What am I doing wrong? Thank you!

void createPlayers(Board b, Rules r, int players)
{
  for(int i = 0; i < players; i++)
  {
    b.listOfPlayers.at(i).cash = r.startCash;
  }

  for(int i = 0; i < players; i++)
  {
    cout << b.listOfPlayers.at(0).cash;
  }
}

typedef struct Player_Struct
{
  int cash;
  vector<char> propertiesOwned;
} Player;

typedef struct Board_Struct
{
  vector<char>listOfProperties;
  vector<Player_Struct> listOfPlayers;
} Board;

Is this even a good way to attack the problem? The number of players is up to the user and I can't initialize a certain number of player_structs in the struct initialization. My thinking is to create a vector list of all the players, then be able to draw information out of each player in the vector list. Am I on the right track, logically at least, even though my code is really bad? I'm still new to C++ just switched from C.

Ol1v3r
  • 758
  • 1
  • 10
  • 23
andyong5
  • 149
  • 9
  • 1
    You do know that in C++ a structure-name (like e.g. `Board_Struct`) is also a type-name, and can be used as a type? Therefore you don't need to define type-aliases (using `typedef`) of structures. – Some programmer dude Jan 19 '18 at 06:29
  • 1
    Furthermore, you do know that symbols needs to be declared *before* they are used? So when you define `Board_Struct::listOfPlayers` the `Player_Struct` symbol must already have been declared. Which it haven't been in your example. Problems unrelated to your main problem that you ask about, like this one, really distracts from the main problem. So if your program builds without errors (and warnings!) then please try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) to show us. – Some programmer dude Jan 19 '18 at 06:32
  • 4
    As for your problem, vectors start out *empty*. Any indexing in them will be *out of bounds*. Perhaps you should [*push back*](http://en.cppreference.com/w/cpp/container/vector/push_back) som actual `Player_Struct` objects into the vector first? And why use the irrelevant `players` variable, when you can get [the size of the vector](http://en.cppreference.com/w/cpp/container/vector/size) directly from the vector itself? – Some programmer dude Jan 19 '18 at 06:33
  • 5
    All in all, it seems you could use [a good beginners book or two](https://stackoverflow.com/a/388282/440558). – Some programmer dude Jan 19 '18 at 06:35
  • Possible duplicate of [C++ vector: std::out\_of\_range Error](https://stackoverflow.com/questions/22067705/c-vector-stdout-of-range-error) – grek40 Jan 19 '18 at 07:54
  • 2
    I can't see c++ here: typedef struct, stand alone functions instead of class and constructors.... And also the variable naming is mysterious: vector is named listxxxxx, while using an "data object" is named as Player_struct. Please start with a simple beginners book of OOP and c++. – Klaus Jan 19 '18 at 12:12

2 Answers2

0

You don't show any outputs nor what the variable values are when the error occurs.

You can reference elements in a vector the same as in a normal array such as b.listOfPlayers[i].

It is better practice to specify library, better to write std::vector<int> than vector<int>.

You don't need to pass players you could simply use a built in function on a vector .size() such as b.listOfPlayers.size().

You don't need to specify typedef on structs.

To sum up what people have said and a little more. Perhaps not the answer you wanted, but the answer you needed.

Jonathan Woollett-light
  • 2,813
  • 5
  • 30
  • 58
-1

I can see how coming from C you would opt to code this project using Structs, but you're using C++, where you can make use of OOP concepts.

Start off by changing structs into classes, this way you can make use of Inheritance, encapsulation, abstraction and polymorphism concepts. Have a look at this. Keep Structs as POD, and use Classes for everything else

If you are learning C++, code in C++ and make use of its features, avoid using C++ as C with classes.

Going back to your original question; If you want to add to a vector, use push_back. In your case listOfPlayers looks to be empty or i is out of bounds, so when you're calling .at as per documentation;

If this is greater than, or equal to, the vector size, an exception of type out_of_range is thrown.

To fix this, add Items to the vector using push_back and make sure that i is within bounds of the vector.

I suggest you read this

Ol1v3r
  • 758
  • 1
  • 10
  • 23
  • 1
    in C++ the keyword `struct` defines a class type. It only differs from `class` in the default access modifier – Caleth Jan 19 '18 at 12:05
  • It does but one should make it clear what's being defined, this is better achieved by using the `class` keyword. – Ol1v3r Jan 19 '18 at 12:14