Jump to content
  • Advertisement
Sign in to follow this  
VanillaSnake21

Overloading new

This topic is 772 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

I'm writing a very basic resource manager, just something to keep track of how much my program has allocated and at the end release everything that wasn't. But as soon as I run anything with these new overloaded functions I soon get an exception for "Stack Overflow" at some location. I can't see the calling stack either, so I can't figure out where it's happening. Is there anything fundamentally wrong with this code that's causing this? 

 

ResourceManager.h

struct ptrdesc
{
	void* ptr;
	size_t size;
};

class ResourceManager
{
public:
	ResourceManager();
	~ResourceManager();

	
	static void releaseAllocatedPointers();
	static unsigned int getAllocatedSpace();
	static void MemoryAllocated(void* p, size_t size);
	static void MemoryDeleted(void* p);

private:
	

	static vector<ptrdesc> m_allocatedPointers;
};

//overlad new and delete
void* operator new(size_t size);
void operator delete(void* p);

 

 

ReourceManager.cpp


vector<ptrdesc> ResourceManager::m_allocatedPointers;

unsigned int ResourceManager::getAllocatedSpace()
{
	size_t totalSpace = 0;
	vector<ptrdesc>::iterator vIter;
	
	for (vIter = m_allocatedPointers.begin(); vIter < m_allocatedPointers.end(); vIter++)
		totalSpace += vIter->size;
	
	return totalSpace;
}

void ResourceManager::releaseAllocatedPointers()
{
	vector<ptrdesc>::iterator vIter;
	for (vIter = m_allocatedPointers.begin(); vIter < m_allocatedPointers.end(); vIter++)
	{
		if (vIter->ptr)
		{
			free(vIter->ptr);
			m_allocatedPointers.erase(vIter);
		}
	}
}

void ResourceManager::MemoryAllocated(void* p, size_t size)
{
	ptrdesc desc;
	desc.ptr = p;
	desc.size = size;

	m_allocatedPointers.push_back(desc);

}

void ResourceManager::MemoryDeleted(void* p)
{
	vector<ptrdesc>::iterator vIter;
	for (vIter = m_allocatedPointers.begin(); vIter < m_allocatedPointers.end(); vIter++)
	{
		if (vIter->ptr == p)
		{
			m_allocatedPointers.erase(vIter);
			break;
		}
	}


}

void* operator new(size_t size)
{
	void* p;
	p = malloc(size);

	if (!p)
	{
		bad_alloc ba;
		throw ba;
	}

	ResourceManager::MemoryAllocated(p, size);
	return p;
}

void operator delete(void* p)
{
	free(p);
	ResourceManager::MemoryDeleted(p);
}

Thanks.

Share this post


Link to post
Share on other sites
Advertisement

Thanks for quick reply, so every time I push an element vector calls new? Is there any way I can get it to allocate memory in one shot in the beginning then or do I have to write one? 

Share this post


Link to post
Share on other sites

Thanks for quick reply, so every time I push an element vector calls new? Is there any way I can get it to allocate memory in one shot in the beginning then or do I have to write one? 

 

 

 
You can use vector's "reserve" member function to tell it to reserve enough capacity for a specified number of items. That will cause it to make only a single allocation (until you try to insert more than that capacity into the vector, and it must expand).
 
You're still going to have the same problem though. You will need a custom allocator for that vector (or you'll need to not use a vector here)

Share this post


Link to post
Share on other sites

@JP. Thanks, I see. So I could just write something vector-like that only works on that particular ptrdesc struct right using my own allocator? Or is there some way to replace the default vector's allocator? Or maybe even there is a better way to do this whole process? I just want to keep track of all the pointers allocated and the amount of space.

Share this post


Link to post
Share on other sites

 

Thanks for quick reply, so every time I push an element vector calls new? Is there any way I can get it to allocate memory in one shot in the beginning then or do I have to write one? 

 

 

 
You can use vector's "reserve" member function to tell it to reserve enough capacity for a specified number of items. That will cause it to make only a single allocation (until you try to insert more than that capacity into the vector, and it must expand).
 
You're still going to have the same problem though. You will need a custom allocator for that vector (or you'll need to not use a vector here)

 

The easiest thing to do is simply take an off the shelf demo allocator that calls directly into malloc. Here's one. Create your vector with that allocator specified in the template and it won't attempt to call back into your own tracking allocator.

Edited by Promit

Share this post


Link to post
Share on other sites

Sorry, I still can't get it to work. So I copied over the allocator from that link but I don't know heads or tails when it comes to templates so I just tired to plug it in directly. I'm not sure if I should have modified it first since the one in the link was made for a map, this is what I have now:

template <class T>
struct allocator { .... } // full definition as copied from above link

//the element that will be in the vector
struct ptrdesc
{
	void* ptr;
	size_t size;
};

typedef vector<ptrdesc, allocator<ptrdesc>>  vector_malloc; //is this right?


class ResourceManager
{
public:
        //.....//

private:
	
 static vector_malloc m_allocatedPointers;
};


And what I get is " 'allocator' ambiguous symbol " as an error, what am I doing wrong? 

 

ed: this is how he shows how to use it:

std::map<std::string, int, std::less<std::string>, JVC::allocator<std::pair<const std::string, int> > > stuff;
Edited by VanillaSnake

Share this post


Link to post
Share on other sites

And what I get is " 'allocator' ambiguous symbol " as an error, what am I doing wrong? 

 

 

 
You created a type called "allocator" in the global namespace. However, you appear to have committed the cardinal sin of employing a using declaration ("using namespace std") in a header file (I can tell this because you wrote "typedef vector" instead of "typedef std::vector"). That means your "allocator" conflicts with standard library's "allocator."
 
Rename your type or (better), remove your using declaration.

Share this post


Link to post
Share on other sites

Yes, that was it. JP to the rescue again ). I wasn't aware that I shouldn't use using in headers? All my files have that, you're saying I should write out the scope to every single std reference? I just threw the allocator in a namespace for now though.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • 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!