#include <iostream>
#include <string>

// We have a house that has an address
struct House
{
    std::string address;
};

// And a region that contains houses
struct Region
{
    House* houses = nullptr;
    unsigned num_houses = 0;
};

// This is how we might add a house to a region:
void add_house(Region& region, const std::string& address)
{
    House* new_houses = new House[region.num_houses + 1];

    for (unsigned i = 0; i < region.num_houses; ++i)
        new_houses[i] = region.houses[i];

    new_houses[region.num_houses].address = address;

    delete [] region.houses;

    region.houses = new_houses;
    ++region.num_houses;
}

void show_region(const Region& region)
{
    std::cout << "This region contains houses at the following addresses:\n";
    for (unsigned i = 0; i < region.num_houses; ++i)
    {
        std::cout << '\t' << region.houses[i].address << '\n';
    }
}

int main()
{
    Region region;
    
    std::cout << "Enter addresses to add houses to a region (or an empty line to stop):\n";
    std::string line;
    while (std::cout << "> ", std::getline(std::cin, line) && !line.empty())
        add_house(region, line);

    show_region(region);

    delete [] region.houses ; // normally this would be done in a destructor.
}