1

I'm trying to understand how pointers and arrays work to dynamically expand memory during run time. I have this program here to illustrate what i'm talking about. Say the user makes int input = 5 and after this program runs its course sName and sID each hold 5 user specified strings. If I wanted to give the user the ability to add more elements after the initial 5, will I have to attempt to create new arrays that will be n+5 (where n is the new number of elements the user wants to add) and then copy the values of sName and sID into those arrays in addition to whatever the user puts in? Or is there a simpler way, other than just using vectors?

#include <iostream>
#include <string>

using namespace std;

int main()
{
int input;
string *sName = NULL;
string *sID = NULL;
string temp, temp2;

cout << "How many names";
cin >> input;

sName = new string[input];
sID = new string[input];

for (int i = 0; i < input; i++)
{
    cout << "Enter name ";
    cin >> temp;
    cout << "enter id ";
    cin >> temp2;
    *(sName + i) = temp;
    *(sID + i) = temp2;
}


    return 0;
}
ZeeZeeZee
  • 73
  • 10
  • Yeah, you will have to copy stuff over. Or use `vector` (seriously, use `vector` ;-) ). You also probably want to increase the size of your array geometrically (eg multiply it by 2 every time), to keep reasonable performance while growing. – Xarn Oct 27 '14 at 09:52

2 Answers2

2

Small initial warning: your code is leaking memory.

That said I can't really understand why you don't want to use vectors for this since it would require much more work to achieve the same, you could allocate a new array of contiguous memory and copy the old elements back (warning: no checked iterators, the following code is highly discouraged and it is provided as an example for illustrative purposes)

// I want 2 additional elements

std::string *sNameOld = sName;
std::string *sIDOld = sID;

sName = new std::string[input + 2];
sID = new std::string[input + 2];

std::copy_n(sNameOld, input, sName);
std::copy_n(sIDOld, input, sID);
delete[] sNameOld;
delete[] sIDOld;

for (int i = input; i < input+2; i++)
{
    std::cout << "Enter name ";
    std::cin >> temp;
    std::cout << "enter id ";
    std::cin >> temp2;
    *(sName + i) = temp;
    *(sID + i) = temp2;
}

for (int i = 0; i < input + 2; ++i) {
    std::cout << sName[i] << " " << sID[i] << std::endl;
}

delete[] sName;
delete[] sID;

I highly recommend to use std vectors since they are the primary choice for the task you're doing by providing heap-based dynamic allocation and being quite flexible at adding new elements by resizing themselves

#include <iostream>
#include <string>
#include <vector>

int main()
{
    int input;
    std::vector<std::string> sName;
    std::vector<std::string> sID;
    std::string temp, temp2;

    std::cout << "How many names";
    std::cin >> input;

    for (int i = 0; i < input; i++)
    {
        std::cout << "Enter name ";
        std::cin >> temp;
        std::cout << "enter id ";
        std::cin >> temp2;
        sName.push_back(temp);
        sID.push_back(temp2);
    }

    return 0;
}

Example

The above code is not even leaking memory.

There is no exact C++ replacement for C's realloc although you might craft something suited for the task, for instance by using placement new.

Reference: C++: What is the proper way of resizing a dynamically allocated array?

Community
  • 1
  • 1
Marco A.
  • 43,032
  • 26
  • 132
  • 246
  • thanks for that detailed response, unfortunately I'm limited to just using arrays. I understand memory leak is something to watch out for but say the above code is just one function within the main. If I wanted to use contents of sName does `delete[] sName` prevent me from using that array again later? – ZeeZeeZee Oct 27 '14 at 10:45
  • Yes, once deleted memory is unreliable (might be collected/used for something else). Only delete when you're sure nobody's using it anymore. – Marco A. Oct 27 '14 at 10:59
  • 1
    @ZeeZeeZee: if you're limited to arrays _by your teacher_, assume that he's teaching C++ as it was 20 years ago - literally. `vector` is not new at all. – MSalters Oct 27 '14 at 12:42
  • @MarcoA. I always thought once the program closes all the memory allocated would be freed. So I guess once I'm done with the list and am about to exit the program I should add a `delete[] arrName` before return 0; – ZeeZeeZee Oct 28 '14 at 09:12
1

for just understanding you are doing it the right way. you have to add n when the array limit is reached. By the way vectors are best suited for such kind of problems they can increase\decrease their size dynamically and automatically.

Ali Kazmi
  • 1,460
  • 9
  • 22