calling destructor versus new object

Started by
45 comments, last by Sigvatr 10 years, 7 months ago

Getting there, it's compiling and functionally working.

Unfortunately a ***load of unfreed memory, not sure if 'destructing' is working fine when I 'reinitalize' the object with 'CScene = engine_IO::CScene();

When I call the destructor manually, right before 're-initializing' the object, there are no memory leaks at all...

When I debug the following happens after the line 'CScene = engine_IO:CScene();

- first the constructor is called

- then the destructor is called

I would expect (and need smile.png) it the other way around..

My suspicion is that the default assignment operator is not working out well, because my CScene class has members that need 'deep copy', pointers/ array of other classes etc. So 2 options (?)

- write a big and clean assignment operator

- go for new/ delete and continue doing fun stuff

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement

If you're doing manual resource management, then no, the default assignment operator won't work. Your class is clearly in violation of the Rule of Three, you should read up on it.

Thanks, clear.
So because I have a non-standard/ own destructor, I also need a DIY copy constructor and assignment operator. In my destructor I delete dynamic arrays which I create when loading a scene. These pointer arrays are set to NULL in the constructor.

All is, IF i use the assignment (=) and copy operators. Which I'm not sure off, but never the less it's good practice.

A few questions:
- can I prevent that in the assignment operator function of the class, the destructor is called at the end of the function (when I return *this)?
- how would the destructors of the member objects of other objects in the class/objects be called, from within my assignment operator function?
- do I have to 'set' every variable manually in the assignment operator function or can I just call the constructor for the new object? Since I want to be able to initiate the object to it's initial values (as already defined in the constructor)?
Or probably I need two versions, one with no function parameter, assigning everything as it is in the constructor, and one version taking over all members from the object in the function parameter.

Sorry for the maybe stupid questions, like to understand how to do the exercise right and efficient.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me


In my destructor I delete dynamic arrays which I create when loading a scene. These pointer arrays are set to NULL in the constructor.

Use std::vector instead of your own dynamic array. If you do, the destructor, copy constructor and assignment operator would automatically do the right thing for you and you don't need to write them.

Thanks Alvaro.
I never found any good reasons to use std::vector, up till now that is :)

I'll get into it. Always thought I'd be wasting memory when I "reserve" to much elements versus giving in performance when not reservering and only use "push back". Maybe I'll do a new reserve of the vectors size +10 every time I've pushed back 10 more elements. To prevent unnecessary copying. Although this 'feels' like using the advantages of std::vector only partially.

That's why up till now I used dynamic arrays with the size I need. The advantage of the std::vector though, is that for example when loading my scene from file, I don't have to do it twice, once for just counting (determine size of dynamic arrays) and once for the actual loading.

If I go for this I think I also have to adopt iterators and use the size() function, instead of looping up to for example mNrLighs or mNrMeshes. I'll probably keep them to not depend on only the size() of each vector. To prevent that all my source files throughout my engine are required to use vectors. Unless my const functions returning for example the number of lights, meshes etc, just return the vector.size() value.

That's quite a lot of changes throughout the whole engine, but with the advantage being good practice and creating future flexibility.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me


If I go for this I think I also have to adopt iterators and use the size() function, instead of looping up to for example mNrLighs or mNrMeshes. I'll probably keep them to not depend on only the size() of each vector. To prevent that all my source files throughout my engine are required to use vectors. Unless my const functions returning for example the number of lights, meshes etc, just return the vector.size() value.

You can iterate a vector without iterators, the same as you would an array, since it provides a subscript operator and at() function. The only difference in your code would be switching from a manually controlled size to the vector's .size(). Of course, iterators are nice because should you ever decide to switch from a vector to some other standard container, you don't have to refactor all your code again.

Thanks Alvaro.
I never found any good reasons to use std::vector, up till now that is smile.png

I'll get into it. Always thought I'd be wasting memory when I "reserve" to much elements versus giving in performance when not reservering and only use "push back". Maybe I'll do a new reserve of the vectors size +10 every time I've pushed back 10 more elements. To prevent unnecessary copying. Although this 'feels' like using the advantages of std::vector only partially.

That's why up till now I used dynamic arrays with the size I need. The advantage of the std::vector though, is that for example when loading my scene from file, I don't have to do it twice, once for just counting (determine size of dynamic arrays) and once for the actual loading.

If you already use your own dynamic vectors with the size you need, then why not use that size to reserve space for the vector as well?

If I go for this I think I also have to adopt iterators and use the size() function, instead of looping up to for example mNrLighs or mNrMeshes. I'll probably keep them to not depend on only the size() of each vector. To prevent that all my source files throughout my engine are required to use vectors. Unless my const functions returning for example the number of lights, meshes etc, just return the vector.size() value.

That's quite a lot of changes throughout the whole engine, but with the advantage being good practice and creating future flexibility.

It's a bad idea to keep track of the size yourself when the vector is already doing that. It introduces more points of failures when you have to ensure that your code is, in fact, always up to date with the vectors: the vectors do that themselves automatically. Switching from your own dynamic arrays to using standard vectors is not something you should just do halfway.

And as Zipster said, you don't have to use iterators to access the vector. You probably already use pointer or array subscript access your own dynamic array, and those methods can still be used with the vector.

Thanks.
Regarding the 1st point, I do have the requested sizes now, but they're gathered going through a file once, and then loaded afterwards, reading the file again.
I think with std::vector I should be able to do that at once, with each next object just 'push back' the next one. And then in the end I know the total number.
When I'm thinking about this, this is probably the answer. After loading I can use the size() function of each array in my const functions, returning the number of meshes, lights etc.

The only disadvantage is when I load the file directly and fill the objects in the array, I don't know the size on forehand, meaning I have to do some reserve actions (maybe after each 10 objects or so). Unless the disadvantage of copying the array of objects, when I exceed the size of the std::vector, is not that bad (since it's only during loading time).

A few last questions:
- is there some sort of default size that's reserved when initializing the std::vector as member of my class?
- will reserving 'x' objects of the std::vector's in my constructor kill the possibility to use the default assignment operator, copy operator and destructor?
- what's more preferable when I "fill" the objects in the std::vector

1. Initialize them first (calling the constructor) and during filling them:
MyVector.member = value, just loop through 'i'

2. Create a local scope object, same object as the vector has.
Fill the local object and then push_back(local object)

Option 1 seems mostly logical when I know the requested number of objects, or else I'd be contructing unnecessary objects (wasting memory). And option 2 when I just continue till I'm done, now knowing how manh objects there will be.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Thanks.
Regarding the 1st point, I do have the requested sizes now, but they're gathered going through a file once, and then loaded afterwards, reading the file again.
I think with std::vector I should be able to do that at once, with each next object just 'push back' the next one. And then in the end I know the total number.
When I'm thinking about this, this is probably the answer. After loading I can use the size() function of each array in my const functions, returning the number of meshes, lights etc.

The only disadvantage is when I load the file directly and fill the objects in the array, I don't know the size on forehand, meaning I have to do some reserve actions (maybe after each 10 objects or so). Unless the disadvantage of copying the array of objects, when I exceed the size of the std::vector, is not that bad (since it's only during loading time).

The question is then: is it more expensive to parse the file once to figure out the number of items, or to relocate the vector a few times?

By the way, is there some sort of default size that's reserved when initializing the std::vector as member of my class?

Visual Studio 2012 appears to not pre-reserve anything by default, and is expanding the vector by 50% every time it has to reserve more memory. This exponential growth is very efficient in the long run as opposed to just reserve an additional fixed number of items as you mentioned in an earlier post.

Will reserving 'x' objects of the std::vector's in my constructor kill the possibility to use the default assignment operator, copy operator and destructor?

No, the vector won't stop working because you tell it to reserve memory before adding items to it.

Thanks. Enough theory and preperation for now, I'll just give it a go (and let you know the results).
Thanks again for the help

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement