|
The typed_mem.h header file provides a C++ like interface to the C functions malloc(.) and friends,
including memcpy(.), fread(.) and the like.
However, before using typed_mem.h, you are strongly recommended to consider using C++'s new and delete operators,
or much better, STL containers like vector or deque, as the latter provide the same functionality and allow
for exception savety and the RAII idiom.
Please consider using typed_mem.h only when you would otherwise use malloc(.) and friends directly.
But if you decide for malloc(.) and friends, the wrappers in typed_mem.h provide you with some advances.
These advances are:
-
Type savety.
The C functions malloc(.) and friends work on void pointers that require type casts and multiplications of number-of-elements
with the size of one element explicitely state in the code. Since the wrapper functions in typed_mem.h wrap both, they always fit together.
You cannot change the type of a variable and forget to update the amount of memory to process.
-
clearer code.
Another advance of hiding type casts and corresponding number-of-elements with size-of-one-element multiplications into a wrapper function is
that you don't see this in your code anymore, and the statements become better readable. E.g. instead of using the idiom memcpy(&DestVar, &SrcVar, sizeof(Var))
you clearly state memcpy(&DestVar, &Srcvar);. But see the Usage section below.
Performance
Performance wise these wrappers should not introduce any runtime costs, as they only call the native C function and should be handled as inline
functions by modern compilers. They just move the type casts and multiplication with element size, which often can be optimized away by the
compiler anyway, to another location in code.
Usage
Usage of the typed_mem.h header file can be sumarized as follows:
|
write |
pFoo= Malloc<foo>(); |
|
instead of |
pFoo= (foo*)malloc(sizeof(foo)); |
|
|
|
write |
pFoo= Malloc<foo>(5); |
|
instead of |
pFoo= (foo*)malloc(sizeof(foo) * 5); |
|
|
write |
pFoo= Realloc(pFoo, 5); |
|
instead of |
pFoo= (foo*)realloc(pFoo, 5 * sizeof(foo)); |
|
|
|
write |
Free(pFoo); |
|
instead of |
free((void*)pFoo); |
|
|
write |
ZeroMem(pFoo); |
|
instead of |
memset(pFoo, 0, sizeof(*pFoo)); |
|
|
|
write |
ZeroMem(pFoo, 5); |
|
instead of |
memset(pFoo, 0, 5 * sizeof(foo)); |
|
|
write |
MemCpy(pDest, pSrc); |
|
instead of |
memcpy(pDest, pSrc, sizeof(*pDest)); |
|
|
|
write |
MemCpy(pDest, pSrc, 5); |
|
instead of |
memcpy(pDest, pSrc, 5 * sizeof(*pDest)); |
|
|
write |
MemMove(pDest, pSrc); |
|
instead of |
memmove(pDest, pSrc, sizeof(*pDest)); |
|
|
|
write |
MemMove(pDest, pSrc, 5); |
|
instead of |
memmove(pDest, pSrc, 5 * sizeof(*pDest)); |
|
And last but not least:
|
|
write |
foo aSomething[5];
for(int C= 0; C<SizeOf(aSomething); C++ ) |
|
instead of |
foo aSomething[5];
for(int C= 0; C<5; C++ ) |
|
The latter is unsafe, because when you change the array
definition you may forget to change it in all dependent
statements.
|
|
And if you want to check the validity of a pointer in Win32,
|
|
write |
AssertMemObj(pFoo); or AssertMemObj(pFoo, 5); |
|
instead of and/or |
ASSERT(!IsBadReadPtr ((void*)pObject, 5 * sizeof(*pObject)));
ASSERT(!IsBadWritePtr((void*)pObject, 5 * sizeof(*pObject))); |
|
and you'll get a distinction between read access and write access for free.
|
|
Download
Please download or review: typed_mem.h
__.-.__ end of document
|