Is it possible to use new to allocate adjacent blocks of memory?

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

Recommended Posts

Hi, I have a class which upon construction creates a specified number of objects of another class using new CObject...etc. I was just wondering if it is possible to have each new command allocate memory adjacent to the block previously allocated. My current thinking is that the only way to do this would be to allocate a large block of memory and then allocate the objects within this large block. Just a guess though! Thanks

Share on other sites
Use an array or std::vector maybe?
Or allocate a single block and use placement new (which is effectively what the above does).

Share on other sites
Well I'm using a linked list so would placement new be best? How exactly do you use it?

Share on other sites
Factory Pattern with Placement New (1, 2, 3) is probably what you are looking for.

You can create a chunk of memory and then use a list to keep track of what in the chunk is available. Have a list for both 'new' and 'used' memory. When an object is deleted/released back to the factory, ensure it is in the used list (to catch bad releases), deconstruct the object, and put the memory back in the free list.

When the factory is being deconstructed, make sure all the memory is in the free list. Then you can free the entire block.

EDIT: I just realized I wrote a journal post about this a lonnngggg time ago. A bit old, but you can look at some of my code here (look at entry for June 19th). I have a full listing of code in the comments of another journal, which can be found here. You might want to read this post to understand some of the design decisions. Please note that the code is VERY OLD and does not necessarily represent what I feel are good design decisions anymore. But you might be able to rip the placement new stuff out.

[Edited by - visage on December 8, 2008 5:18:47 AM]

Share on other sites
Are you sure you need to be using a linked list?
I've been trying to find a good reference which explains the trade offs between different collection types, but haven't had much success (anybody know any good links?).
Anyway if you have to use a linked list, and are doing alot of insertion and deletion (otherwise why use a linked list?), then you are not going to be able to keep memory usage contiguous (in a single block), without doing alot of reallocation and copying. In that case you may aswell just use an std::vector.

Share on other sites
Ok thanks guys, I've been looking at placement new and I now have an array of objects that I allocatoe like so:

//Class propertyCObject< Type >* m_Data;//...in constructorm_Data = new CObject< Type >[Size];

Thing is when I do it this way it's throwing up a linker error LNK2001.
Strange because if I do it with a base type (like int) it works fine.

p.s. the CObject template class DOES have a default constructor...

Share on other sites
Quote:
 Original post by DOrmisherOk thanks guys, I've been looking at placement new and I now have an array of objects that I allocatoe like so://Class propertyCObject< Type >* m_Data;//...in constructorm_Data = new CObject< Type >[Size];Thing is when I do it this way it's throwing up a linker error LNK2001.Strange because if I do it with a base type (like int) it works fine.p.s. the CObject template class DOES have a default constructor...

The parameter type you are using may be missing a default constructor; I assume you are creating an instance of 'Type' somewhere in CObject<Type>.

Share on other sites
Well type is a template type. But no worries anyway the problem was with my CObject destructor...problem sorted.

Thanks

Share on other sites
My little test code of your problem works fine:
#include "stdafx.h"template < class T >class CObject{	T* tptr;public:	CObject() : tptr(NULL) {}};template < class T >class TestClass{	CObject < T >* obs;public:	TestClass () 	{		obs = new CObject < T > [5];	}	~TestClass()	{		delete[] obs;	}};int _tmain(int argc, _TCHAR* argv[]){	TestClass<int> tclass;	return 0;}

What are you doing that is different from that?

P.S what you mention is not placement new, just the array version of new. Placement new constructs an object at a location in memory that has been previously allocated and looks like:

void* place = operator new(sizeof(Something));Something* p = new (place) Something();

/edit
oops too slow!

Share on other sites
Quote:
 Original post by DOrmisherWell type is a template type. But no worries anyway the problem was with my CObject destructor...problem sorted.Thanks

Ya it is obviously a template type :). I just meant that you could be creating one when you created the template class, if I had of looked at the original post more carefully i would have seen that you do not, doh :)

Share on other sites
Ah so that isn't placement new?? What about if I do it like this...
m_Data = operator new (sizeof (CObject< Type >[ Size ]) );//and then when allocating memory...obj = new (m_Data) CObject< Type >();

Thing is if I do it this way, every time I allocate a a new obj to the block of memory like above. Will it not just overwrite the previous allocation?

Share on other sites
Quote:
 Original post by DOrmisherI was just wondering if it is possible to have each new command allocate memory adjacent to the block previously allocated.

No (for non-placement new), because (a) the concept of "adjacent" is already blurred by the OS, and (b) that memory might not be available.

Quote:
 My current thinking is that the only way to do this would be to allocate a large block of memory and then allocate the objects within this large block. Just a guess though!

Which is basically what std::vector does; except that it also has enough smarts to start out with a smallish block and (periodically, as the need is proven) re-allocate a larger block and move (by copying and then destroying the original) elements to there, then deallocate the smaller block.

Quote:
 Well I'm using a linked list

If this is a linked list you made yourself, and the only reason you're using it is because it's the only way you know to manage an unknown-ahead-of-time-sized collection, then you need to re-educate yourself.

If not, you should be aware that simply allocating each new node in sequential memory offers little performance benefit, while forcing the elements to appear sequentially in memory defeats the purpose of using a linked list (as opposed to, say a vector) entirely.

In any case, my recommendation is to just try std::vector<T>, remove any logic you might have for maintaining an "internal" linked list, and see how that works for you. Placement new is tricky business that you shouldn't have to worry about yourself. If 'CObject' (and WTF is a cobject, anyway?) is a polymorphic base class, you will probably instead want to use boost::ptr_vector, or a vector of some kind of smart pointer class, instead. (But the same is true if you were using std::list.)

Share on other sites

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

Create an account

Register a new account

• Forum Statistics

• Total Topics
628719
• Total Posts
2984386

• 25
• 11
• 10
• 15
• 14