Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

graveyard filla

could someone explain why... (constructors and dynamic memory)

This topic is 5279 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

high, this has been bothering me for awhile and now id like to figure it out... I have been having some problems with constructors. For all of my classes, i have an Init() function.. this is because i have such problems with construtors, but now id like to get rid of these ugly Init() functions... heres the problem : i have a bunch of global objects. Player, list < Enemy >, Map, System, Messages, ETC.. i have global instances of all of these classes. Now, inside the constructor for say Player or Enemy, i would try to do something like this: texture = systm.Load_Texture("path"); ERROR! doesnt work because systm and this object are global, which means when this constructor is called systm doesnt even exist yet! (systm is a global object of type System) ok, this happends with lots of things, where one classes constructor would depend on another class.. so i gave each class an Init() function and just called it in the begining of main... this "solved" my problem.. now on to my next problem : dynamic memory that is part of a class. lets say i do this to my Enemy class:
Enemy::Enemy()
{
   somenumber = new int;
}
~Enemy::Enemy()
{
   delete somenumber;
}
  
if i try doing something like this, the game will crash when it first starts up. if i log " CONSTRUCTOR CALLED" or "DESTRUCTOR CALLED", i get 3 extra destructor calls (there just so happends to be 3 enemies, too)... i think this is because im using a list. when i read in an enemy from a map, i will do something like: Enemy temp; temp.x = blah; temp.y = blah; enemy_list.push_back(temp); right about now is where my log tells me "const called, dest called" for each enemy... then, at the end of the game, when the enemies fall out of scope, i get 3 calls to destructors... where do those 3 calls to constructors go that should have went? i think i have to do something with a copy constructor but i tried that and no luck (i probably did it wrong)... thanks for any help!! [edited by - graveyard filla on June 7, 2004 2:05:21 AM] [edited by - graveyard filla on June 7, 2004 2:46:41 AM]

Share this post


Link to post
Share on other sites
Advertisement
what code do you want me to post? my small example on my enemy constructor/ destructor should do it, my code is pretty much the same.. then i push_back Enemies onto an < Enemy > list which i showed in my example.. for some reason the contructor isnt being called enough times / the destructor is being called 1 too many times... thanks for any help

Share this post


Link to post
Share on other sites
To begin with, a good rule to remember is

anything you new, delete.
anything you new[], delete[].

So { someint = new int; free someint; } is not good, but
{ someint = new int; delete someint; } is.

Also, with vectors, the rule is

copy in, copy out

so somewhere, your copy constructor is being called without you knowing. That''s fine unless you are using dynamic memory, or some other instance tracking method.

Hit the books.




blah blah blah.

Share this post


Link to post
Share on other sites
ok, to get rid of the Inits,

instead of creating the object globally, create a pointer globally and then dynamically create the object in Main().

this will invoke the constructor only when you''re good and ready.


next problem,

if you use the new operator to allocate memory, use the delete operator deallocate.

The free operator is used in C only if you use malloc to allocate your memory.

Share this post


Link to post
Share on other sites
hey guys,

thanks for your replies. that was a typo (i was just giving you a small example).. yes, in my code it does say delete of course...

quote:
Original post by Chris Hare
T
Also, with vectors, the rule is

copy in, copy out

so somewhere, your copy constructor is being called without you knowing. That''s fine unless you are using dynamic memory, or some other instance tracking method.

Hit the books.




blah blah blah.


could you please explain to me WHAT and WHY this is happening? i suppose its true for all STL containers? when and why is my copy constructor being called? and how do i fix this if i dynamically allocate in my constructor / delete in my destructor? i think i have to make my own copy constructor, but i dont understand what to put inside it..

i didnt think of making a pointer to get around the other problem... guess ill be doing that, maybe make it static member of the class? and isnt this what a singleton does? thanks again!

Share this post


Link to post
Share on other sites
try checking to see if it is null before you delete and then set it to null afterwards. This prevents it from being deleted twice, which would crash.

example:
if (somenumber) delete somenumber;
somenumber = null;

it would be a good idea to set the pointer to null in a constructor.

so

enemy()
{
somenumber = null;
}

~enemy()
{
if (somenumber) delete somenumber;
somenumber = null;
}

void Initiate()
{
somenumber = new int;
}



Initate functions are very useful in most cases.

Share this post


Link to post
Share on other sites
Lets follow the code:

Enemy temp; // new integer is created at 0x7f000000
temp.x = blah; // unimportant
temp.y = blah;
enemy_list.push_back(temp); // A new enemy is created using default constructor. It''s somenumber pointer is also pointing to 0x7f000000

// We fall out of scope, things started getting destroyed.
// The enemy in enemy_list is destroyed, it deletes the pointer at 0x7f000000
// temp is destroyed, it attempts to delete the pointer at 0x7f000000 too, but it''s already been deleted. The universe explodes.


This is fixed with a copy constructor:


Enemy::Enemy(const Enemy &enemy)
{
somenumber = new int;
*somenumber = *enemy.somenumber;
}


Now instead of getting a copy of the other enemies pointer, it gets it''s own, and they will both delete their own different pointers.

You''ll also want to write an assignment operator for a similar reason!

Share this post


Link to post
Share on other sites
quote:
Original post by graveyard filla
hey guys,

thanks for your replies. that was a typo (i was just giving you a small example).. yes, in my code it does say delete of course...

quote:
Original post by Chris Hare
T
Also, with vectors, the rule is

copy in, copy out

so somewhere, your copy constructor is being called without you knowing. That''s fine unless you are using dynamic memory, or some other instance tracking method.

Hit the books.




blah blah blah.


could you please explain to me WHAT and WHY this is happening? i suppose its true for all STL containers? when and why is my copy constructor being called? and how do i fix this if i dynamically allocate in my constructor / delete in my destructor? i think i have to make my own copy constructor, but i dont understand what to put inside it..

i didnt think of making a pointer to get around the other problem... guess ill be doing that, maybe make it static member of the class? and isnt this what a singleton does? thanks again!



This depends on what operators and constructor you''ve provided.

First case is when you don''t provide any of them no copy constructor, no assignment operator. Then a default is generated for you what happens is:

for copy constructor its going to do:


Enermy(const Enermy& e): _member1(e.member1), _member2(e.member2) {}


for the assignment operator its going to do:


Enermy& operator=(const Enermy& e) {
_member1 = e._member1;
_member2 = e._member2;

return *this;
}

You may not wont the default.

Next case is when you provide a copy constructor but no assignment operator, then when you make an assigment like this:

 enmery1 = enermy2  


its going to use the copy constructor to make that assignment

Last case is when you provide them all and your explicitly stating that copying constructor and assignment op are different from the default and from each other.

When i remember looking at your code in the other thread you didn''t have a proper assignment operator but had copy constructor. When your using an STL container and add an element to it, depending on how you added it means it''s either been by assignement or construction but as you''ve not got a proper assignment operator its using your copy constructor instead.

Share this post


Link to post
Share on other sites
smart idiot - thank you!! this is exactly what i was looking for!

i just have a question, when is this copy constructor called? when i do this?

enemy_list.push_back(temp);

is this copying temp into the back element of enemy_list? so really, im calling my copy constructor and sending temp as the parameters? so the constructor is never called, but the destructor of course has to be called no matter what. we fix this by allocating new memory for the pointer, and then copying the VALUE of the old pointer into the new one.. now i understand why it was crashing and why ive been having these problems... thanks again!!!

lastly, lets say that the int that i allocate in the constructor, isnt really an int. in fact, it isnt. its a pointer to a Weapon. Weapon is a base class from which my weapons derive from, such as Smg, Pistol, Flamethrower... this is why my Enemy (and Player) has a pointer, so i can do something like current_weapon = new Flamethrower(), and current_weapon = new Smg();. so, is there any trick to figure out which type of object the pointer points to?
ie,

if(current_weapon == Flamethrower) current_weapon = new Flamethrower();
else if (current_weapon == Pistol)
current_weapon = new Pistol();

or do i have to hard-code it as Smg() or whatever? thanks again for all your help!!!

[edited by - graveyard filla on June 7, 2004 3:51:20 AM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!