Can't delete a pointer that I declared in a constructor

Started by
16 comments, last by Conny14156 10 years, 9 months ago

Oh, and in this piece of code:


Entity::Entity()
{
	FactoryComponent cFactory;
	AddComponent(cFactory.ComponentInstantiate<TransformComponent>());
	AddComponent_S(cFactory.ComponentInstantiate_S<TransformComponent>());
}

'cFactory' is created on the stack there. It's not a member-variable of Entity, which means cFactory will be destroyed and its destructor called. Is that intentional?

Advertisement

I found the problem now, I think.



void Entity::AddComponent_S(BaseComponent* type)
{
	if(ComponentList_S.count(type->getTypeName()) == 0)
	{
		type->setHolder(this);//<----- This line
		ComponentList_S.insert(std::make_pair(type->getTypeName(),type));
	}
}

When I add a component, I also assign the entity that the component is added to with the line above,

The problem is when I push_back its copy the value, which mean it also copy the soon to be "dead" entity, the testing object.

So in my vector its a "new" entity, but with the same value of my old one, so inside the transform component its holds the pointer towards the "dead" entity. so when I try to delete the object it gets a error as I guess it goes crazy when it look at that pointer. Which may explain why it works when I add the transform component outside the constructor cause the "holder " of the transform component gets a correctly pointer towards a "living" holder, but should it really be a problem?

I guess I will try to make the vector of pointers instead of value's, so that nothing changes, will be back soon when I gets some good results

Oh, and in this piece of code:


Entity::Entity()
{
	FactoryComponent cFactory;
	AddComponent(cFactory.ComponentInstantiate<TransformComponent>());
	AddComponent_S(cFactory.ComponentInstantiate_S<TransformComponent>());
}

'cFactory' is created on the stack there. It's not a member-variable of Entity, which means cFactory will be destroyed and its destructor called. Is that intentional?

About that yeha its intentional, I was deciding if I wanted to have one factory inside my global class header, but I won't be really needing the same one as its only a creating method, so instead of wasting some memory I decided to just declare a new one whenever I need to add a component, still in the exprimenting phase. I don't think its a bad idea to let the factory die? as its doesn't contribute to anything after it creates the component

Adding 'TransformComponent' in the Entity's constructor like you want, try this:


Global->EntityController.NewEntity("blan"); //TransformComponent already created in Entity's constructor.
Entity* TestObject = Global->EntityController.RequestEntity("blan");

assert(TestObject->GetComponent_S<TransformComponent>(), "Oops, it was already deleted");

See whether the assert is triggered or not.

Just tested it, No messages comes up. As I think it should if there is a problem right?

If you do this:


BaseComponent *component = new DerivedComponent;
BaseComponent notAPointer = *component;

You are 'slicing' the object.

How many files is your project? If it's only two or three files, could you upload them to someplace like Ideone.com, and post the links, so we can see the entire code? I feel like I'm looking at a puzzle with half the pieces missing. smile.png

What do these two methods ?


        it->second->Release();
        delete it->second; //<--- Crashing here

Ensure, that they are not overlapping, e.g. 'Release' deletes internal data while the destructor does it too. Maybe you forgot to set a pointer to NULL after deleting it in Release and you try to delete it a second time in the destructor.

If you do this:


BaseComponent *component = new DerivedComponent;
BaseComponent notAPointer = *component;

You are 'slicing' the object.

How many files is your project? If it's only two or three files, could you upload them to someplace like Ideone.com, and post the links, so we can see the entire code? I feel like I'm looking at a puzzle with half the pieces missing. smile.png

Yeah I know about the slicing problem, but It should be fine right? as its just basepointer that points to a derived pointer, and when I try to retrieve the component I just cast it upwards again.


template<class T_S>
T_S* GetComponent_S()	
{
	std::string test = typeid(T_S).name();
	std::map<std::string,BaseComponent*>::iterator it;
	//"Class" + " "
	for(int i = 0; i < 6 ;i++)
	{
		test.erase(test.begin());
	}
	it = ComponentList_S.find(test);
	
	if(it != ComponentList_S.end()) 
	{
		T_S* ptTComponent;
		ptTComponent = (T_S*)it->second;
			return ptTComponent;
	}
	else 
		return NULL;
	//*/
}

And I don't mind uploading my project, but I don't think you want me to :l seeing as there's about 56 files, but most of files is not related toward this,and its probably one of the uggliest thing you ever see in you lifetime :x. as this project is just a learning project for me. Where I have been doing "crazy" and stupid stuffs, to help me try understanding coding.

But I think I solved the problem now, Instead of having a vector<Entity> I just made it a vector<Entity*> to prevent it from copying a dead object.

if you still want me to upload it I can or perhaps just the files that you may want?, and am still intresterd in knowing why I get that error as it may help me prevent myself from doing the same in the future.

P.S

if it matter I get this same reading violation adress 0xfeeefeee.

P.S.S

Another theory which may be the problem

When I use this code


Global->EntityController.NewEntity_S("blan");

It will Trigger


void EntityHandler::NewEntity(std::string name)
{
	Entity testing;
	testing.name = name;
	TotalEntity.push_back(testing);
}

Here the testing entity gets push_back into the Vector, but the vector "copies" the entity. so after the end of this function, testing will die, so it will call upon the destructor. Seeing as the destructor is been call upon, it will free the memory of the transformcomponent that gets added in the constructor.

So when the program ends it will try to delete the same memory, which already been deleted. and seeing how its "technially" two diffrent object, like twin. the testing transform component gets "zero-fied"(Not sure if this is even a word, I mean that the pointer gets equal to = 0 ), the second twin doesn't as it copies the state of the other twin before it.

Which explains why when I made the vector from <Entity> to <Entity*> it suddenly works again, cause the same memory adress only gets "deleted" once.

P.SSS

if the text made no sense is that when I was going to upload the idea struck me and I started write this second section :x. sorry for all the confusingness.

oh while am at it.

If we say that I still want to go with a vector<Entity> instead of pointers version, what is a good idéa to prevent this? seeing that it won't work just to see if the pointer is null or not. is there a way to check if its possible to see if a certain adress already been deleted?

What do these two methods ?


        it->second->Release();
        delete it->second; //<--- Crashing here

Ensure, that they are not overlapping, e.g. 'Release' deletes internal data while the destructor does it too. Maybe you forgot to set a pointer to NULL after deleting it in Release and you try to delete it a second time in the destructor.

Yeha, Release did what the deconstructor did, so I just copied the whole release function inside the destructor, but now it just leftover code. Doesn't matter if its there or not :x sorry for confusing you guys, but its still there because I may have some use for it sometimes in the future :l

This topic is closed to new replies.

Advertisement