-1

How do I add an element to the end of an array dynamically in C++?

I'm accustomed to using vectors to dynamically add an element. However, vectors does not seem to want to handle an array of objects.

So, my main goal is having an array of objects and then being able to add an element to the end of the array to take another object.

EDIT** Sorry, its the pushback() that causes me the problems.

class classex
{
private:
    int i;

public:
    classex() { }
    void exmethod()
    {
        cin >> i;
    }
};

void main()
{
    vector <classex> vectorarray;
    cout << vectorarray.size();
    cout << vectorarray.push_back();
}

Now I know push_back must have an argument, but What argument?

LihO
  • 41,190
  • 11
  • 99
  • 167
andrew Patterson
  • 559
  • 2
  • 6
  • 19
  • 7
    "However, vectors does not seem to want to handle an array of objects"? Can you please clarify this, perhaps with an example of where you've tried to do this and what went wrong? – johnsyweb Feb 11 '12 at 21:03
  • 1
    Can you explain why "vectors does not seem to want to handle an array of objects"? – Joseph Mansfield Feb 11 '12 at 21:03
  • 3
    `vectors does not seem to want to handle an array of objects` Let's focus on this. This is your real question. Let's figure out what that means, before you jump to the conclusion that you need to switch to a technology that's not designed to do what you want, from a technology that explicitly is. – Lightness Races in Orbit Feb 11 '12 at 21:03
  • I didn't understand what's wrong with using std::vector ? – Asaf Feb 11 '12 at 21:05
  • Vectors are even compatible with C API, choose vector, they mostly replace Fixed size array :) – Mr.Anubis Feb 11 '12 at 21:09
  • Your assertions make no sense. Vectors are precisely the sort of dynamic data structure that you want and need. – Kerrek SB Feb 11 '12 at 21:13

3 Answers3

1

Arrays are fixed sized containers. So enlarging them is not possible. You work around this and copy one array in a bigger and gain space behind the old end, but that's it.

You can create a array larger than you currently need it and remember which elements are empty. Of course they are never empty (they at least contain 0's), but that's a different story.

Like arrays, there are many containers, some are able to grow, like the stl containers: lists, vectors, deques, sets and so on.

add a Constructor to set i (just to give your example a real world touch) to your example classex, like this:

class classex {
public:
    classex(int& v) : i(v) {}
private:
    int i;
};

An example for a growing container looks like this:

vector <classex> c; // c for container
// c is empty now. c.size() == 0

c.push_back(classex(1));
c.push_back(classex(2));
c.push_back(classex(3));
// c.size() == 3
Jörg Beyer
  • 3,631
  • 21
  • 35
1

Now I know push_back must have an argument, but What argument?

The argument is the thing that you want to append to the vector. What could be simpler or more expected?

BTW, you really, really, really do not want exmethod as an actual method of classex in 99% of cases. That's not how classes work. Gathering the information to create an instance is not part of the class's job. The class just creates the instance from that information.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
-2

EDIT: The question was how to add an element to an array dynamically allocated, but the OP actually mean std::vector. Below the separator is my original answer.

std::vector<int> v;
v.push_back( 5 ); // 5 is added to the back of v.

You could always use C's realloc and free. EDIT: (Assuming your objects are PODs.)

When compared to the requirement of manually allocating, copying, and reallocating using new and delete, it's a wonder Stroustrup didn't add a keyword like renew.

SplinterOfChaos
  • 469
  • 3
  • 12
  • 3
    Not in C++, in general. That's undefined behaviour. – Kerrek SB Feb 11 '12 at 21:13
  • Could you give me a source for that? I found NOTHING about malloc being undefined behaviour with google, and if that were to be true, wouldn't #including C libraries in your C++ code break it? I even remember reading that the compiler's implimentation of new is allowed to call malloc. Also, if you're right, then C++ is not backwards compatible with C, which was a major design choice. – SplinterOfChaos Feb 11 '12 at 21:22
  • 2
    `realloc` is problematic, because you're not allowed to move an object's memory around (imagine if the object stores a pointer to one of its members). This is a direct consequence of 3.8(1) (object lifetime). – Kerrek SB Feb 11 '12 at 21:24
  • If you want an array to be resizable, you don't want to assume it'll be the same place in memory all the time anyway, so passing a straight pointer around would be just as silly as passing around vector::iterators. (No different from using new and delete to reallocate.). A vector is basically a T*&, which is what i'd pass around. Though, my answer is still actually wrong because the OP wanted to use a vector, not an array. – SplinterOfChaos Feb 11 '12 at 22:57
  • No, still not. C++ has *objects*, and objects have *lifetime*, and they must be *constructed*. You cannot simply move an object's memory representation around, since there wouldn't *be* an object at the new location. You really need to reconstruct a new object at the new location. No such thing as a "renew" would make sense, but maybe [this question of mine](http://stackoverflow.com/questions/8003233/does-stdvector-have-to-move-objects-when-growing-capacity-or-can-allocator) is of some ancillary interest. – Kerrek SB Feb 11 '12 at 23:11
  • If the type is a POD, then moving the binary representation is well defined behaviour, but that has to be specified. I'll add that to my answer. Otherwise, you're right, realloc doesn't work. Funny, we both had a point, but one of us was looking from the perspecitve of PODs and the other non-PODs. – SplinterOfChaos Feb 12 '12 at 00:36
  • Well, if you don't qualify your answer, it has to be assumed to be true for the general case. And given that PODs are not "typical" C++ objects, `realloc` would really only be a niche solution which incurs the danger of later breakage if the type definition changes. As I said in my linked question, it would be cute to have a `reallocate` interface specification, along with a tweaked `realloc` that would only either grow or fail, but that wasn't considered important enough. – Kerrek SB Feb 12 '12 at 00:40