Question about constructor/destructor in a vector pointer

Hi everyone,

First, here's the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <vector>

using namespace std;

class MyClass
{
    public:
    //Constructor
    MyClass() { cout << "\n\tBuilding Class."; }
    ~MyClass() { cout << "\n\tDestroying Class."; }

};

int main()
{
    vector<MyClass> * pClassObjects = new vector<MyClass>(8);
    delete pClassObjects;

    return 0;
}


Here's my question: Why is the constructor called only once in the output, but destroyed 8 times? (well 9, but that would be the vector)

I can understand that new vector<MyClass>(8); should initialize 8 elements of MyClass in the vector, but it certainly doesn't call the constructor in the output.

But it calls the destructors each time for the objects (plus once for the vector) even though it didn't call the constructor for them to begin with. Why?

Thanks for your time!
It allocates 8 elements of std::vector<MyClass>, not 8 elements of MyClass in the vector.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <vector>

using namespace std;

class MyClass
{
    public:
    //Constructor
    MyClass() { cout << "\n\tBuilding MyClass."; }
    ~MyClass() { cout << "\n\tDestroying MyClass."; }
};

int main()
{
    vector<MyClass *> classObjects(8);

    for(int i = 0; i < classObjects.size(); ++i)
    {
        classObjects[i] = new MyClass();
    }

    //clean up
    for(int i = 0; i < classObjects.size(); ++i)
    {
        delete classObjects[i];
    }

    return 0;
}


This one now allocates 8 elements of MyClass, correct? Which one would be more efficient in your opinion?

Thanks!
Last edited on
It allocates 8 elements of std::vector<MyClass>, not 8 elements of MyClass in the vector.


No it doesn't. Probably what's happening is that one element is default constructed and the rest are copy constructed from the first. You could test that by defining the copy constructor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <vector>

class MyClass
{
public:
    MyClass() { std::cout << "\n\tBuilding MyClass - Default constructor." ; }
    MyClass(const MyClass&) { std::cout <<"\n\tBuilding MyClass - Copy constructor."; }
    ~MyClass() { std::cout << "\n\tDestroying MyClass." ; }
};

int main()
{
    std::vector<MyClass> objects(8) ;
}



VC++11 does what's expected. 8 elements are default constructed.

This one now allocates 8 elements of MyClass, correct? Which one would be more efficient in your opinion?

The first. Although they both unnecessarily use pointers.

[edit: Fixed the destructor copy and paste error.]
Last edited on
Vector's single-argument constructor used to default-construct one element and copy-construct the rest in C++03, and it default-constructs all elements in C++11, because vectors can now hold non-copyable objects.

Oh, and the better way to write that is of course
1
2
3
4
int main()
{
    vector<MyClass> classObjects(8);
}

Last edited on
Thanks for the answers, it makes sense.

The first. Although they both unnecessarily use pointers.


Of course I was only whipping up a quick example to better understand pointers created on the heap, but when would you say pointers would be appropriate then?

I mean, I thought I understood that instantiating an object on the heap has to be referenced by pointers.

Edit: I also get an error because you have added an argument to the destructor. Doing a quick search lead me to this, as specified in Section §12.4 of C++0x draft n3290:

Destructors

A special declarator syntax using an optional function-specifier (7.1.2) followed by ˜ followed by the destructor’s class name followed by an empty parameter list is used to declare the destructor in a class definition.


Is there a reason why VC++ 11 lets you do that?
Last edited on
Is there a reason why VC++ 11 lets you do that?

Just a copy and paste error. Sorry about that - corrected.

Of course I was only whipping up a quick example to better understand pointers created on the heap, but when would you say pointers would be appropriate then?

I should've said avoid explicit dynamic memory usage where you don't have to, but it's equally true of pointers. Only manually manage dynamic memory when you absolutely have to, and only use pointers where pointer semantics are required. Neither is the case here. Explicit dynamic memory usage isn't required, and neither are pointers.

Ok, thanks for the quick answer.

Although I'm still not sure why you advocate avoiding dynamic memory usage. I'm still figuring stuff out and trying to understand when to use the heap and when to use the stack, but I was planning on building something using the heap because I'd want to create long-lived objects, or if I don't know how many objects I'd need to allocate.

I'd love to hear your opinion on this if you'd care to elaborate.

Thanks for your time!
If you are just worried about using the heap to store your information, that is exactly where std::vector stores the data. You use std::vector to avoid using pointers and dynamic memory, that is why they were designed.

Although I'm still not sure why you advocate avoiding dynamic memory usage.

Using dynamic memory is one of the most error prone parts of the language. Anytime you can avoid using dynamic memory, do it. Let the container handle the messiness of memory allocation and deallocation.
Marcan wrote:
Although I'm still not sure why you advocate avoiding dynamic memory usage.

I didn't advocate that.
cire wrote:
avoid explicit dynamic memory usage where you don't have to


Marcan wrote:
I'm still figuring stuff out and trying to understand when to use the heap and when to use the stack, but I was planning on building something using the heap because I'd want to create long-lived objects, or if I don't know how many objects I'd need to allocate.

Those are great reasons to use containers (e.g. std::vector) which manage the dynamic memory for you.
I didn't know that vectors stored their data on the heap. I coincidentally just read this in the following article, which I really liked by the way:
http://andrewbrobinson.com/2012/01/07/when-to-use-the-heap-in-c/

If I understood correctly, the vector class is calling a destructor by itself when the vector falls out of scope (if the vector was created on the stack) to clear all the data it stores on the heap.

By the way cire, I didn't mean to say you didn't advocate it, you just seemed to have a perfectly valid opinion about why dynamic memory allocation should be avoided and I really wanted to hear about it. I didn't mean to put words in your mouth (language barrier and all.)

Anyways, thanks for all the answers guys! Great discussion, I learned a lot.
Last edited on
Topic archived. No new replies allowed.