1

Here is my own Point class (Point.h):

class Point {
public:
    Point(double x, double y, double z);
    Point(const Point& orig);
    virtual ~Point();
    double getX();
    double getY();
    double getZ();
    void writeOut();
private:
    double x, y, z;
};

Here I create a point and add it to the vector<Point> (main.cpp):

Point* p = new Point(0.1,0.2,0.3);
vector<Point>* points = new vector<Point>;
points->push_back(*p);
//doing stuff
delete points;

My question: is vector making a copy of the Point and store it (so I need to delete p; too), or is it storing the one instance created before?

UPDATE:

I read here that push_back "Adds a new element at the end of the vector, after its current last element. The content of val is copied (or moved) to the new element." But which one? Copied or moved? How is it determined?

adtewa
  • 189
  • 10
  • 7
    C++ is not Java or C#. You don't need all of those calls to `new` to create objects. `Point p(0.1, 0.2, 0.3); vector points; points.push_back(p);` – PaulMcKenzie Mar 02 '16 at 18:10
  • 2
    You store a copy of the object pointed to by p – Martin G Mar 02 '16 at 18:10
  • 2
    Why all this `new` / `delete` stuff. Do you have a particular reasoning doing this? – πάντα ῥεῖ Mar 02 '16 at 18:13
  • @πάνταῥεῖ yes my original code is more complicated than this, i simplified it for the question. (And I like doing new and delete) – adtewa Mar 02 '16 at 18:20
  • @SimonÁdám I have "complicated code" and nowhere do I create vectors using `new`. What you post, even though it is small, creates an impression that this is what you would do even for a tiny program. Second, this is a much better reference to `push_back`: http://en.cppreference.com/w/cpp/container/vector/push_back – PaulMcKenzie Mar 02 '16 at 18:23
  • copy or move depends on the type of the parameter (lvalue,rvalue,..), and whether the implementation of the type (Point) permits it. – Thomas Mar 02 '16 at 18:24
  • 2
    If you *simplified* to buttloads of pointers, I recommend a time-out to stop and do a re-think. – user4581301 Mar 02 '16 at 18:24
  • @SimonÁdám You may want to have a look at [smart pointers](http://en.cppreference.com/w/cpp/memory), and decide if you really think you need to manage that yourself. – πάντα ῥεῖ Mar 02 '16 at 18:27
  • The main reason not to use `new` is memory leaks, *as demonstrated in the code you posted*. You allocate memory for the `p` variable, but you never delete it. If you simply *declared* the variable, the compiler would take care of construction and destruction. The destruction occurs at the end of the scope that it was declared in. Since the compiler is destroying the variable, no memory loss or leaks occur. – Thomas Matthews Mar 02 '16 at 20:54

1 Answers1

6

The vector points is storing a copy of the Point that is passed through push-back (*p).

In your code, when points is destructed (through delete), the contained objects will be destructed, but not the pointer you created with new Point (p), since a copy was created.

If you don't need to be using dynamic allocation (and in this case it seems you don't), just treat everything as a stack-allocated object and pass that.

Point p{ 0.1, 0.2, 0.3 };
std::vector<Point> points;
points.push_back(p);
// Do stuff with points

Otherwise, if you'd need dynamic allocation, use something like std::unique_ptr or std::shared_ptr (or another smart pointer) so that when the vector is destructed, the pointers contained are as well.

Point *p = new Point{ 0.1, 0.2, 0.3 };
std::vector<std::unique_ptr<Point>> points;
points.push_back(std::make_unique<Point>(0.1, 0.2, 0.3));

Generally, with move semantics in C++11, most of the time you will likely not need to manage memory (use new and delete) with something like this.

It is determined whether an object passed into push_back is copied or moved based on whether it is an rvalue or not. For more information, read this answer on move semantics. As mentioned, you can also use std::vector::emplace_back to guarantee no copies are performed.

Community
  • 1
  • 1
Alyssa Haroldsen
  • 3,652
  • 1
  • 20
  • 35
  • That really doesn't answer the question wrt whether deleting `p` is necessary or not in the OPs code. – Thomas Mar 02 '16 at 18:14