初学C++的时候,总有一个疑惑,就是比如
int* p = new int[10];
delete[] p;
delete的时候是怎么知道new的大小的,后来有听前辈解释说是编译期的new 的是把内存块的大小保存在这块内存前段,delete的时候就知道了。
感觉听上去是挺有道理,也就没追究了。其实也还是一直都没看到那个所以保存大小的地址。
今天在群里看到一个这样的题目,让我重新学习了下。
char* p = new char[5;
cin>>p //超过4个字符,不会出错
delete[] p //报错
起先一直不知道为什么在delete得时候才出错,后面切换到release下就不会出错了,
初步断定,应该是vc在debug下对堆内存使用是否合法一种检测机制。
接下来就是跟下代码,终于发现:
debug下,New调用的
_malloc_dbg,
会在你申请空间的基础上,多分配一块空间来保存这样的结构
这块空间就在申请内存的前部
typedef struct _CrtMemBlockHeader
{
// Pointer to the block allocated just before this one:
struct _CrtMemBlockHeader *pBlockHeaderNext;
// Pointer to the block allocated just after this one:
struct _CrtMemBlockHeader *pBlockHeaderPrev;
char *szFileName; // File name
int nLine; // Line number
size_t nDataSize; // Size of user block
int nBlockUse; // Type of block
long lRequest; // Allocation number
// Buffer just before (lower than) the user's memory:
unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;
{
// Pointer to the block allocated just before this one:
struct _CrtMemBlockHeader *pBlockHeaderNext;
// Pointer to the block allocated just after this one:
struct _CrtMemBlockHeader *pBlockHeaderPrev;
char *szFileName; // File name
int nLine; // Line number
size_t nDataSize; // Size of user block
int nBlockUse; // Type of block
long lRequest; // Allocation number
// Buffer just before (lower than) the user's memory:
unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;
nDataSize 就是保存了大小,
现在回到刚才说到delete出错的原因
unsigned char gap[nNoMansLandSize];
gap[]内容是被0XFD填充,并且在申请的内存结束部分也填充4byte的0XFD
两个4byte的0XFD就夹着我们申请内存,
在delete时候调用_free_dbg,
在_free_dbg里面会检测内存前部和后部4byte内容是否还是为0xFD,若被改写,就会报错