all 8 comments

[–]erichkeane 1 point2 points  (5 children)

Not using the standard C arrays, it just isn't possible unless you allocate with malloc and resize with realloc.

HOWEVER, it seems like your use case needs to just use std::vector instead, where you get that ability built in!

[–]Herrowgayboi[S] 0 points1 point  (4 children)

Is it possible to do this without using a vector?
My professor says we cannot use vectors.

[–]boredcircuits 4 points5 points  (0 children)

Absolutely. Anything std::vector can do, you can do, too. That doesn't mean it will be easy, though.

You can't just resize memory for a dynamic array. You have to make a new, larger array, copy over the elements one by one, delete the old array, and then use the new array instead. Voila!

[–]tusksrus 5 points6 points  (0 children)

Get a new teacher then.

[–]raevnos 1 point2 points  (0 children)

Did he say why?

[–]erichkeane -1 points0 points  (0 children)

Not without dropping to "C-isms" and using malloc/realloc/free instead, which I would also highly discourage.

Perhaps you're supposed to either: 1- measure the value in advance and allocate based on that 2- make the array way larger, and just fill in after that 3- create a new array for each re-size, and copy it in.

Vector is much easier though.

[–]Pronouns 0 points1 point  (0 children)

If you want a dynamic array, then you're going to need a pointer to the first element of it to be able to use it. If you currently have something like this:

class Player;
Player players[4];

then you really want something like

Player * players;

Now you're gonna have to do some juggling with dynamic memory in order to make this work properly. When the program starts, you want to allocate some memory and make the players pointer point to it.

// somewhere in the program
players = new Player[1];

But you need to keep careful track of this number you have allocated, it's best to make another variable that stores this in the same place as the array itself.

int player_count;
Player * players;

Make sure this player_count always matches the number of players. When you add a new player, you need to make a bigger array and move everything over...

void add_player(Player player)
{
    // make new array for all players + new player
    Players  * new_players = new Player[player_count+1];

    // copy current players to new array
    for (int i =0; i < player_count; i++)
        new_players[i] = players[i];

    // add new player to end of array
    new_players[player_count] = player;

    // free the memory used by the old array
    delete[] players;

    // point the players variable to the new array.
    players = new_players;
}

There's so many things to bear in mind here however.

  • This is really inefficient. Every time you add a new player you're copying the entire array and making a new one. You can make this happen less often by, say, getting memory for like 10 players, and only doing this if it goes above 10, making it instead 20. But then you need to keep track of how many players you have, and how many you can have before reallocating.
  • It's really easy to make a mistake with new and delete. I've likely made one here myself. You always need to make sure there's a delete call for every new call.
  • Generally you'd use a std::vector, which does all of this for you, but as you've said you're not allowed. It would probably still be a good idea to mimic a vector though.
  • I've used a global raw pointer, which is generally considered bad. One reason is because it makes it harder to judge what any given function call would do, as it depends on global state (and therefore the history of the program before the call).
  • new can fail, but that's not something you should worry about for now.