Размещение объектов в заданых областях памяти.

Рубрика: C++, Дата: 20 April, 2013, Автор:

Здорова господа!

Тут вообщем не могу решить задачку без знаний как размещать объекты в заданной области памяти, поэтому в этом посте попытаемся как не будь разобраться как их размещать. Ну что ж летс го.

Для начала определимся, что такое за тип size_t. size_t – это базовый без знаковый целочисленный тип.

Так же нам нужно знать как перегружать операторы new и delete “перегрузка new и delete”

Пришлось мне разобрать, что такое Placement new. Я вам так вкратце скажу своими словами это когда сразу выделяется большой объем байтов, а затем уже он как бы размечается тем же самым оператором new . Приведу вам сразу же примерчик который я переделал с википедии:

//vudelenie pam9ti placement new
#include <iostream>
using std::cout;
using std::endl;

class A
{
public:
	int val;
	A(int x):val(x){}
};

int main()
{
	int size=50;
	//Cdec6 mu vedel9em pam9t6 (gromadnyyu pam9t6 pod macciv)
	//ob9zatel6no nyjno dobavl9t6 clovo operator, inache ne rabotaet owibka
	A* memory=static_cast<A*>(operator new[](size*sizeof(A)));

	//cdec6 mu procto razmechaem ety pam9t6 kak bu vudelenie ne proicxodit
	for(int i=0;i<size;i++)
	{
		new(memory+i)A(i);//kak bu razmechaem memory+i eto adrecc, a A(i) eto razmer
	}

	//vuvod rezyl6tatov pocle razmetki
	for(int i=0;i<size;i++)
	{
		cout <<i<<' '<<(memory+i)->val<<endl;
	}

	//i ydalenie 
	operator delete [] (memory);

	return 0;
}

Мы в примере выделили памятьA* memory на размером 50 умножить на sizeof(A) на размер объекта A, то есть у нас в область памяти на которую указывает указатель memory может поместиться 50 объектов A. Естественно мы этот указатель создали с помощью преобразования типов static_cast<A*>() которому передали в качестве параметра operator new[](50*sizeof(A)). Как бы указатель мы передали функция должна вернуть указатель на область памяти.

Как мы ее размечаем? Мы просто берем в цикле 50 раз вызываем new которому передаем адрес выделенной памяти и объект который нужно туда разместить, ну и в итоге он просто походу по порядку берет и в уже выделенную память втуливает этот объект, то есть мы два параметра как бы передаем new отаким вызовом new(memori+i) A(), где meroi+i это наверняка адрес памяти, а A это встраиваемый объект. Да это вообще получается мы просто встраиваем объект типа А в выделенную память memory.

Ладно мне если честно это не сильно понятно.

Теперь давайте попробуем встроить один объект на то выделенное место которое занимает второй объект, то есть заместить объекты, как бы так. Я уже пробовал писать но я создавал не через new а через malloc() и у меня получалось фигово, вообщем не так как нужно, как бы у меня новая память выделялась.

Так приведу я вам просто пример где мы встраиваем в объект Arena объект X без перегрузки.

#include <iostream>
using std::cout;
using std::endl;

class X
{
public:
	int val;
	int k;
	X(int a):val(a){}
};

class Arena
{
public:
	Arena():a(0){}
	Arena(int b):a(b){}
	int a;
};

int main()
{
	Arena a(7);
	
	Arena* p=new(Arena);
	cout <<"sizeof(p)= "<<sizeof(p)<<endl;
	X* xPtr=new(p)X(4);
	cout <<xPtr<<' '<<p<<endl;
	
	p=&a;
	X* x2Ptr=new(p)X(8);
	cout <<x2Ptr<<' '<<p<<' '<<&a<<endl;
	cout <<sizeof(x2Ptr)<<' '<<sizeof(p)<<' '<<sizeof(&a)<<endl;
	
	return 0;
}

Наглядно видно, что у них адреса памяти одинаковые одни и теже, то есть как бы встроился поверх объект X поверх объекта Arena.

Так и что я еще хотел добавить так это выделение памяти при перегрузке оператора operator new() вот код:

//razmechenie ob6ekta v zadannux blokax pam9ti
#include <iostream>
using std::cout;
using std::endl;
#include <cstdlib>
using std::exit;

//klacc kotorui bydet razmechatc9
class X
{
public:
	//int val2;
	int val;
	X(int a):val(a){}
};

class Arena
{
public:
	virtual void* alloc(size_t)=0;
	virtual void free(void*)=0;
	//...
};

class Arena_1 : public Arena
{
public:
	virtual void* alloc(size_t size)
	{
		cout <<size<<' '<<sizeof(this)<<endl;
		if(size<=sizeof(this))
			return this;
		else
		{
			cout <<"razmer pomechaemogo ob6ekta bol6we chem pam9t6"<<endl;
			exit(1);
		}
	}
	virtual void free(void* p)
	{
		free(p);
	}
};

void* operator new(size_t size, Arena* a)
{
	a->alloc(size);
}

int main()
{
	cout <<sizeof(Arena)<<' '<<sizeof(X)<<endl;
	
	Arena_1 a1;
	
	X* p=new(&a1)X(7);
	
	cout <<p->val<<endl;
	cout <<&a1<<' '<<p<<endl;//odinakovue adreca
	
	return 0;
}

Это я привел пример с функциями и классами из книги. Вообщем там такая фигня была.

[youtube]http://www.youtube.com/watch?v=2uPyqwj8CJM[/youtube]

Комментарии:


Оставить комментарий

Your email address will not be published. Required fields are marked *