struct a{
int b;
bool s;
double f;
};
int main(int argc, char* argv[])
{
a* hehe=new a[120];
int cout=*(int*)(hehe-1)/sizeof(hehe[0]);
printf("Hello World!/n");
return 0;
}
如 上,在实际一个项目中需要通过线程池批量的写入数据,批量数据为对内分配的一个数组,如同:a* hehe=new a[120];然后线程池函数只能接受一个VOID*,本来打算用一个结构传进取,结构包含数组的元素个数,不过我觉得VC应该没那么傻吧!结果还真是 傻,没有一个函数可以正确分析出数组的大小,使用sizeof(数组指针)的到的也只是指针的大小。一个简单的问题卡住了老半天,结果用GOOGLE搜索 了下,发现了上面的那种用法。及编译器在堆上分配数组时实际上分配多了一个元素在数组首元素前,其记录了数组的大小。如上通过前移指针强制转化为整型后可 获得数组分配的字节数,除单个元素的大小便求得了数组的元素个数。经过测试验证没有任何问题,不过心中还是忐忑不安。毕竟对数组堆内分配的原则没有见过详 细的资料描述。不过如果适合项目的应用测试没有问题不妨一试。
#include <malloc.h>
struct a{
int b;
bool s;
double f;
};
int main(int argc, char* argv[])
{
a* hehe=new a[15];
int cout=_msize(hehe)/sizeof(a);
delete [] hehe;
printf("Hello World!/n");
return 0;
}
经过在网上再次论证,正确方式如上才是合理的。
另网上还有以下论述:
一般用new[]申请的内存块中,第一个地址的前32个字节存储的是关于这块内存的信息,有如下结构体表示:
typedef struct tagCRTMEMBLOCKHEADER
{
_CrtMemBlockHeader* pBlockHeaderNext;
_CrtMemBlockHeader* pBlockHeaderPrev;
LPTSTR szFileName;
int nLine;
UINT nDataSize;
int nBlockUse;
LONG lRequest;
BYTE gap[4];
}CrtMemBlockHeader, *pCrtMemBlockHeader;
这个结构占32字节的长度
比如你new了一块内存:
char *a = new[500];
你可以这样获得大小:
CrtMemBlockHeader *Ptr = (CrtMemBlockHeader*)(a-32);
Ptr->nDataSize;//这就是你要的大小了!!!!!!!!
实际上_msize也是通过获得数组的CrtMemBlockHeader* pHead来获得nSize = pHead->nDataSize;
_CRTIMP size_t __cdecl _msize_dbg (
void * pUserData,
int nBlockUse
)
{
size_t nSize;
_CrtMemBlockHeader * pHead;
/* verify heap before getting size */
if (_crtDbgFlag & _CRTDBG_CHECK_ALWAYS_DF)
_ASSERTE(_CrtCheckMemory());
#ifdef _MT
_mlock(_HEAP_LOCK); /* block other threads */
__try {
#endif /* _MT */
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
/* CRT blocks can be treated as NORMAL blocks */
if (pHead->nBlockUse == _CRT_BLOCK && nBlockUse == _NORMAL_BLOCK)
nBlockUse = _CRT_BLOCK;
if (pHead->nBlockUse != _IGNORE_BLOCK)
_ASSERTE(pHead->nBlockUse == nBlockUse);
nSize = pHead->nDataSize;
#ifdef _MT
}
__finally {
_munlock(_HEAP_LOCK); /* release other threads */
}
#endif /* _MT */
return nSize;
}
总算弄明白了。第一种算法误打误撞,刚好往上移了16个字节刚好得到了pHead->nDataSize,建议采用_msize。