[C/C++] Smart Pointer

posi90

Erfahrenes Mitglied
Hallo,

Ist es möglich die Speicherverwaltung eines std::unique_ptr zu "overriden"?

Denn ich reserviere meinen Speicher mit:
Code:
HANDLE mHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
StdCallThunkCode *thunkcode = (StdCallThunkCode*)HeapAlloc(mHeap, 0, sizeof(StdCallThunkCode));

Und gebe ihn wieder frei mit:
Code:
HeapFree(mHeap, 0, thunkcode);
HeapDestroy(mHeap);

Nun möchte ich gerne die Variable thunkcode und in die HeapCreate/HeapAlloc Funkionen einen Smart Pointer stecken.

Wie kann man das elegant lösen?

Freue mich über jeden Tipp. Danke im Voraus!
 
Hallo posi90

Das ist eigentlich nicht so kompliziert, unique_ptr können mit deletern arbeiten. Hier ein Beispiel:
C++:
class MemoryPool
{
	HANDLE mHeapRegular;
	HANDLE mHeapExec;

	struct PoolDeleter
	{
		HANDLE mHeap;

	public:
		void setHeap(HANDLE hHeap) {
			mHeap = hHeap;
		}

		template<typename T>
		void operator () (T* ptr) {
			HeapFree(mHeap, 0, ptr);
		}
	};

	PoolDeleter mExecFree, mRegularFree;

public:
	MemoryPool() {
		mHeapRegular = HeapCreate(0, 0, 0);
		mHeapExec = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);

		mExecFree.setHeap(mHeapExec);
		mRegularFree.setHeap(mHeapRegular);
	}

	template<typename T, typename... Args>
	T* _new(const Args&... args) {
		LPVOID memory = HeapAlloc(mHeapRegular, HEAP_ZERO_MEMORY, sizeof(T));
		return new (memory) T(args...);
	}

	template<typename T>
	void _delete(T* memory) {
		HeapFree(mHeapRegular, 0, memory);
	}

	template<typename T>
	std::unique_ptr<T, PoolDeleter> alloc(bool execute = false) {
		T* ptr = reinterpret_cast<T*>(HeapAlloc(execute ? mHeapExec : mHeapRegular, HEAP_ZERO_MEMORY, sizeof(T)));
		return std::unique_ptr<T, PoolDeleter>(ptr, execute ? mExecFree : mRegularFree);
	}
};

Und die Verwendung dazu:
C++:
class Foo
{
public:
	Foo(int param) {
		std::cout << param << std::endl;
	}
};

int main() {
	MemoryPool pool;
	{
		class Deleter
		{
		private:
			MemoryPool& mPool;

		public:
			Deleter(MemoryPool& pool) : mPool(pool) {

			}

			void operator () (Foo* ptr) {
				mPool._delete(ptr);
			}
		};

		std::unique_ptr<Foo, Deleter> fooPtr(pool._new<Foo>(3), Deleter(pool));

		auto ptr = pool.alloc<int>();
	}
}

Viele Grüsse
Cromon
 
Danke Cromon für den Code!

Hab mir daraus eine tolle Klasse machen können, war wirklich nicht so schwierig.

Danke nochmal und einen schönen Nachmittag!
 
Zurück