I'm fairly new to c++ and started writing a small poker game to help me get some more experience with vectors. I'm getting a runtime error in the second function, which is really no surprise after reading the post below and discovering I was misunderstanding the behavior of the reserve() class member.  I believe I could probably remedy this with resize() but I was hoping for some creative input on a way that I could re-construct this function to allocate dynamically.  The difficulty I'm having with the dynamic allocation is that I am trying to make the deal function distribute cards to each player as in a real card game (yes I realize that this is somewhat statistically superfluous).  I could do this with pointer math in c fairly easily, and I think I could fix this by statically allocating some of these vectors, but I would prefer to utilize c++ as elegant and efficient as possible.  Any suggestions on a way to do this dynamically? That is, how can I completely avoid allocating or reserving space for the containers used in the deal() function?
Choice between vector::resize() and vector::reserve()
#include <cassert>
#include <algorithm>
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>
const int __handSize__ = 5;
class Hand {
public:
    std::vector<int> held;
    std::vector<int> played;
};
std::vector<int> shuffle() {
    std::vector<int> deck;
    for( int i = 0; i < 52; i++ ){
        deck.push_back( i );
    }
    std::random_shuffle(deck.begin(), deck.end());
    assert( 52 == deck.size() );
    return deck;
}
std::vector<Hand> deal( int nPlayers, std::vector<int> &deck ) {
    std::vector<Hand> playerHands;
    playerHands.reserve( nPlayers );
    for( int i = 0; i > __handSize__; i++ ) {
        for( int j = 0; j < nPlayers; j++ ) {
            playerHands.at(j).held.push_back( deck.back() );
        }
    }
    return playerHands;
}
int main() {
    srand(time( NULL ));
    std::vector<int> deck = shuffle();
    std::vector<Hand> hand = deal( 3, deck );
    std::cout << hand.at(1).held.at(1) <<std::endl;
}
output:
dmf86@tux3:~/src/poker$ ./poker
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check: __n (which is 1) >= this->size() (which is 0)
Aborted
Back trace:
#0  0x00007ffff74aa428 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:54
#1  0x00007ffff74ac02a in __GI_abort () at abort.c:89
#2  0x00007ffff7ae484d in __gnu_cxx::__verbose_terminate_handler() ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff7ae26b6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff7ae2701 in std::terminate() ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff7ae2919 in __cxa_throw ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff7b0b3f7 in std::__throw_out_of_range_fmt(char const*, ...) ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x000000000040218c in std::vector<int, std::allocator<int> >::_M_range_check(unsigned long) const ()
#8  0x0000000000401785 in std::vector<int, std::allocator<int> >::at(unsigned long) ()
#9  0x0000000000401030 in main ()
 
     
    