- 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)
}
foxes 10.03.2016 21:37 # 0
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();
};
foxes 11.03.2016 09:06 # 0
-Eugene- 12.03.2016 11:28 # −1
А в чем назначение MEMNULL? Зачем нужен неаллоцируемый в куче объект?
bormand 12.03.2016 12:08 # +2
Чтобы его не аллоцировали в куче...
К слову, из не nothrow оператора new нельзя возвращать NULL. Это UB, т.к. никто не проверяет результат обычного new...
bormand 12.03.2016 12:19 # +2
Искренне надеюсь, что автор не для этого его запилил...
foxes 12.03.2016 13:05 # 0
bormand 12.03.2016 13:13 # 0
Ну на них же никто никогда не сможет позвать new... Почему бы не оставить для них дефолтные реализации операторов (которые всяко не попадут в бинарник, даже если сгенерятся, т.к. никто их не вызовет)?
> генерации исключения
И где же оно, кхм, генерится? Возврат NULL'а из new - просто провокация на UB. О чём нам как бы намекает gcc, если вернуть просто NULL, а не ту самую глобалку.
P.S. Если хочешь невызываемые new/delete - просто в приват их спрячь, да и всё... И реализации им не пиши.
foxes 12.03.2016 13:30 # 0
Например: я делаю что то на подобии вектора который не должен создаваться new MyVec. например этот класс содержит всего один указатель внутри и сам по себе является оберткой к динамическому объекту у которого нет определенного типа, а следовательно и размера. То есть для таких классов делать new тоже самое что делать new void*. Соответственно тот кто так сделает получит исключение.
bormand 12.03.2016 13:38 # 0
1) Вызвать new, delete, new[], delete[] для этого типа невозможно, компилятор сразу об этом скажет (т.е. не надо ждать запуска программы и мифического исключения).
2) Кода у этих методов вообще нет (о чём тебе скажет линкер, если уберёшь private и всё-таки вызовешь). Гарантии:
foxes 12.03.2016 13:51 # 0
Предположим что мне все таки нужно вызвать new MyVec - это для динамических случаев, кода у меня есть ассоциативный список конструкторов для имен классов.
Опять же достаточно добавить class export foo.
bormand 12.03.2016 13:57 # 0
Так твой MEMNULL надо юзать на глобальном уровне, а не внутри классов?
> в твоем примере
Где она? Линкер меня обманывает, когда говорит, что её нету?
foxes 12.03.2016 14:12 # 0
> Предположим что мне все таки нужно вызвать new MyVec
bormand
> Где она?
foxes
> а в моем случает это будет только один new
bormand
> а не внутри классов?
template <typename T>
class MapName {
public:
MEMNULL
...
}
Antervis 14.03.2016 07:04 # 0
bormand 14.03.2016 07:27 # 0
bormand 12.03.2016 14:20 # 0
И получить NULL? Может проще не добавлять такие классы в список создаваемых по имени, раз всё равно ничего полезного не получится?
> class export foo
Это какая-то фишка msvc? Она помечает все методы класса как dllexport, даже приватные?
foxes 12.03.2016 14:31 # 0
нет только для public, написал же выше.
// * MSVC - компилятор Microsoft Visual C++
// * INTEL - компилятор Intel C++
// * BORLAND - компилятор Borland C++
// * GCC - компилятор GNU C/C++
// * MINGW - компилятор MinGW
кажется после MINGW я забил на твой вариант в некоторых классах. А может это был GCC для Эльбруса.
foxes 12.03.2016 14:42 # 0
Да для общего стиля - где куча кода заменяется на одну инструкцию и просто генерит 0.
Реально можно много чего не делать и просто взять готовое. Например BOOST. Или поставить MEMNULL и без заморочек получить размер проекта в 96кб. http://www.gamedev.ru/files/?id=104502
kegdan 12.03.2016 13:01 # 0