- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
namespace bt {
#define MEMNULL \
_FORCEINLINE void* operator new(size_t) { return 0; } \
_FORCEINLINE void operator delete(void* ) { }
#define MEMDEFAULT(classname) \
_FORCEINLINE void* operator new(size_t size) { return extFunctions.CreateMem((unsigned int)size, 0); } \
_FORCEINLINE void operator delete(void* val) { extFunctions.DeleteMem(val, 0); }
#define MEMMANAGER(classname) \
_FORCEINLINE void* operator new(size_t size) { return bt::internalmemmanager.getNew((unsigned int)size); } \
_FORCEINLINE void operator delete(void* val) {bt::internalmemmanager.freeThis(val,sizeof(classname));}
#define MEMMANAGERCLEAN(classname) \
_FORCEINLINE void* operator new(size_t size) { return bt::internalmemmanager.getNewClean((unsigned int)size); } \
_FORCEINLINE void operator delete(void* val) { bt::internalmemmanager.freeThis(val,sizeof(classname)); }
class memManagerExport {
public:
MEMDEFAULT(memManagerExport)
BT_API memManagerExport(unsigned int size);
BT_API virtual ~memManagerExport();
/// destroy all memory segments and free list of free pointers
BT_API void _free();
/// return pointer to new object and create new segment of objects if need.
BT_API void *_addAlloc();
/// return pointer to free object
BT_API void *_getFree(unsigned int size);
/// add pointer to list of free
BT_API void _appendToFree(_voidint idat);
/// mark pointer to free ???
BT_API void _markFree(void* val);
/// return number object in segment
BT_API unsigned int _valid(unsigned int id);
/// return segment number
BT_API unsigned int _segid(unsigned int id);
/// prepare calculation for object size
BT_API void _calcsize(unsigned int size);
private:
enum States {
VALIDED = 0x011F1C01,
FREE = 0
};
unsigned int fisVal;
struct p_smemManager *fargs;
};
class memManager: public memManagerExport {
public:
MEMDEFAULT(memManager)
_FORCEINLINE memManager(unsigned int size):memManagerExport(size) {}
_FORCEINLINE ~memManager() {}
/// create memory for object
_FORCEINLINE void *getNew(unsigned int size) {return (void*)_getFree(size);}
/// delete memory for object
_FORCEINLINE void freeThis(void * val) {_appendToFree((_voidint)val);}
/// destroy all memory segments and free list of free
_FORCEINLINE void free() {_free();};
};
class globalMemManager {
public:
MEMDEFAULT(globalMemManager)
}
BT_API globalMemManager();
BT_API ~globalMemManager();
/// выделяет сегмент быстрой памяти из имеющегося запаса
BT_API void* getNew(unsigned int size);
/// выделяет сегмент быстрой памяти из имеющегося запаса
BT_API void* getNewClean(unsigned int size);
/// освобождает сегмент быстрой памяти для повторного использования
BT_API void freeThis(void*val,unsigned int size);
/// выделяет сегмент памяти стандартными средствами если сегмент запрашиваемого размера не обслужывается.
BT_API void* cashalloc(unsigned int size);
/// освобождает сегмент памяти проверяя способ его выделения.
BT_API void cashfree(void* val,unsigned int size);
/// Обработчик многопоточных блокировок использования памяти
BT_API void manage();
_FORCEINLINE volatile bool &lock() { return flock; }
_FORCEINLINE volatile _voidint &lockId() { return flockid; }
_FORCEINLINE volatile _voidint &canLeave() { return fcanleaveid; }
tfSTDCALL_uint_FUNC isThread;
/// текущий уровень выравнивания памяти
_FORCEINLINE unsigned int _olevel() {return olevel;}
private:
enum States {
VALIDED = 0x011F1C01,
FREE = 0
};
unsigned int fisVal;
struct p_globalMemManager *fmanagers;
unsigned int olevel;
volatile bool flock;
volatile _voidint flockid;
volatile _voidint fcanleaveid;
unsigned int alignSize(unsigned int size);
_voidint alignPointer(_voidint p);
void init();
void cleaner();
};
А в чем назначение MEMNULL? Зачем нужен неаллоцируемый в куче объект?
Чтобы его не аллоцировали в куче...
К слову, из не nothrow оператора new нельзя возвращать NULL. Это UB, т.к. никто не проверяет результат обычного new...
Искренне надеюсь, что автор не для этого его запилил...
Ну на них же никто никогда не сможет позвать new... Почему бы не оставить для них дефолтные реализации операторов (которые всяко не попадут в бинарник, даже если сгенерятся, т.к. никто их не вызовет)?
> генерации исключения
И где же оно, кхм, генерится? Возврат NULL'а из new - просто провокация на UB. О чём нам как бы намекает gcc, если вернуть просто NULL, а не ту самую глобалку.
P.S. Если хочешь невызываемые new/delete - просто в приват их спрячь, да и всё... И реализации им не пиши.
Например: я делаю что то на подобии вектора который не должен создаваться new MyVec. например этот класс содержит всего один указатель внутри и сам по себе является оберткой к динамическому объекту у которого нет определенного типа, а следовательно и размера. То есть для таких классов делать new тоже самое что делать new void*. Соответственно тот кто так сделает получит исключение.
1) Вызвать new, delete, new[], delete[] для этого типа невозможно, компилятор сразу об этом скажет (т.е. не надо ждать запуска программы и мифического исключения).
2) Кода у этих методов вообще нет (о чём тебе скажет линкер, если уберёшь private и всё-таки вызовешь). Гарантии:
Предположим что мне все таки нужно вызвать new MyVec - это для динамических случаев, кода у меня есть ассоциативный список конструкторов для имен классов.
Опять же достаточно добавить class export foo.
Так твой MEMNULL надо юзать на глобальном уровне, а не внутри классов?
> в твоем примере
Где она? Линкер меня обманывает, когда говорит, что её нету?
> Предположим что мне все таки нужно вызвать new MyVec
bormand
> Где она?
foxes
> а в моем случает это будет только один new
bormand
> а не внутри классов?
template <typename T>
class MapName {
public:
MEMNULL
...
}
И получить NULL? Может проще не добавлять такие классы в список создаваемых по имени, раз всё равно ничего полезного не получится?
> class export foo
Это какая-то фишка msvc? Она помечает все методы класса как dllexport, даже приватные?
нет только для public, написал же выше.
// * MSVC - компилятор Microsoft Visual C++
// * INTEL - компилятор Intel C++
// * BORLAND - компилятор Borland C++
// * GCC - компилятор GNU C/C++
// * MINGW - компилятор MinGW
кажется после MINGW я забил на твой вариант в некоторых классах. А может это был GCC для Эльбруса.
Да для общего стиля - где куча кода заменяется на одну инструкцию и просто генерит 0.
Реально можно много чего не делать и просто взять готовое. Например BOOST. Или поставить MEMNULL и без заморочек получить размер проекта в 96кб. http://www.gamedev.ru/files/?id=104502