The correct solution is to not use a manual array at all, use the STL's std::vector
container instead, eg:
#include <vector>
#include <string>
struct Friend
{
std::string name = "";
int daysSinceContact = 0;
};
struct User
{
std::string name = "";
std::string password = "";
std::vector<Friend> friends;
};
...
std::vector<User> usersInformation(5);
...
Friend newFriend;
newFriend.name = "John";
newFriend.daysSinceContact = 2;
usersInformation[0].friends.push_back(newFriend);
// Or simpler:
usersInformation[0].friends.emplace_back(Friend{"John", 2});
That being said, if you really want to manage the array manually, you need to do something more like this instead (which includes implementing the Rule of Five to prevent corrupting and leaking memory):
#include <string>
struct Friend
{
std::string name = "";
int daysSinceContact = 0;
};
struct User
{
std::string name = "";
std::string password = "";
int numberOfFriends = 0;
Friend *friends = new Friend[numberOfFriends];
// default constructor (nothing extra that isn't already done above)
User() = default;
// copy constructor
User(const User &src) :
name(src.name),
password(src.password),
numberOfFriends(src.numberOfFriends),
friends(new Friend[numberOfFriends])
{
for(int i = 0; i < numberOfFriends; ++i)
friends[i] = src.friends[i];
}
// move constructor
User(User &&src) :
name(std::move(src.name)),
password(std::move(src.password)),
numberOfFriends(numberOfFriends),
friends(src.friends)
{
src.friends = nullptr;
src.numberOfFriends = 0;
}
// destructor
~User()
{
delete[] friends;
}
// copy assignment operator
User& operator=(const User &src)
{
if (this != &src)
{
Friend *newFriends = new Friend[src.numberOfFriends];
for(int i = 0; i < src.numberOfFriends; ++i)
newFriends[i] = src.friends[i];
name = src.name;
password = src.password;
delete[] friends;
friends = newFriends;
numberOfFriends = src.numberOfFriends;
}
return *this;
}
// move assignment operator
User& operator=(User &&src)
{
name := std::move(src.name);
password = std::move(src.password);
Friend *oldFriends = friends;
friends = src.friends;
src.friends = oldFriends;
int oldNumber = numberOfFriends;
numberOfFriends = src.numberOfFriends;
src.numberOfFriends = oldNumber;
return *this;
}
// addition helper
void addFriend(const std::string &name, int daysSinceContact = 0)
{
Friend *newFriends = new Friend[numberOfFriends + 1];
for(int i < 0; i < numberOfFriends; ++i)
newFriends[i] = friends[i];
newFriends[numberOfFriends].name = name;
newFriends[numberOfFriends].daysSinceContact = daysSinceContact;
delete[] friends;
friends = newFriends;
++numberOfFriends;
}
};
Or this, which is slightly safer in terms of memory management:
#include <string>
#include <utility>
#include <algorithm>
struct Friend
{
std::string name = "";
int daysSinceContact = 0;
};
struct User
{
std::string name = "";
std::string password = "";
int numberOfFriends = 0;
Friend *friends = new Friend[numberOfFriends];
// default constructor (nothing extra that isn't already done above)
User() = default;
// initializing constructor
User(int initialCapacity) :
friends(new Friend[initialCapacity])
{
}
// copy constructor
User(const User &src) :
User(src.numberOfFriends),
name(src.name),
password(src.password),
numberOfFriends(src.numberOfFriends)
{
std::copy(src.friends, src.friends + src.numberOfFriends, friends);
}
// move constructor
User(User &&src) :
name(std::move(src.name)),
password(std::move(src.password)),
numberOfFriends(0),
friends(nullptr)
{
std::swap(friends, src.friends);
std::swap(numberOfFriends, src.numberOfFriends);
}
// destructor
~User()
{
delete[] friends;
}
// copy assignment operator
User& operator=(const User &src)
{
if (this != &src)
User(src).swap(*this);
return *this;
}
// move assignment operator
User& operator=(User &&src)
{
src.swap(*this);
return *this;
}
// swap helper
void swap(User &other)
{
std::swap(name, other.name);
std::swap(password, other.password);
std::swap(numberOfFriends, other.numberOfFriends);
std::swap(friends, other.friends);
}
// addition helper
void addFriend(const std::string &name, int daysSinceContact = 0)
{
User temp(numberOfFriends + 1);
std::copy(friends, friends + numberOfFriends, temp.friends);
temp.friends[numberOfFriends] = Friend{name, daysSinceContact};
std::swap(friends, temp.friends);
++numberOfFriends;
}
};
Either way, then you can do this:
User *usersInformation = new User[5];
...
usersInformation[0].addFriend("John", 2);
...
delete[] usersInformation;