您的位置:首页 > 其它

free如何知道释放内存长度:vs与glibc分配内存时编译器内部处理

2015-09-29 14:58 447 查看
鉴于网上这个资料实在太少,将以前整理过却未完全的一篇文章贴出来,希望大牛指正vs下内存管理方式。可联系gaoshiqiang1987@163.com

vs分配内存

vs没有源码,编译器在分配内存时,分配给用户的地址减去16个字节(注1),保存了分配内存的类型与大小
如下表示了vs编译器在分配内存时编译器的处理,代码如下:

int _tmain(int argc, _TCHAR* argv[])
{
char *pcMem = (char *)malloc(8);
short *psMem = (short *)malloc(12);
int *piMem = (int *)malloc(16);
long *plMem = (long *)malloc(20);
float *pfMem  = (float*)malloc(32);
double *pdMem = (double*)malloc(48);

system("PAUSE");
return 0;
}






vs2008本地断点调试运行,对应地址分配如下

pcMem    0x007722c8 "屯屯屯屯铪铪"    char *
psMem    0x00772310    short *
piMem    0x00772358    int *
plMem    0x007723a8    long *
pfMem    0x00779230    float *
pdMem    0x00779290    double *


如下为pChar减去16个字节的地址内容

0x007722B8  08 00 00 00 01 00 00 00 7a 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd fd fd fd fd ab ab ab ab
0x00772300  0c 00 00 00 01 00 00 00 7b 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd fd fd fd fd
0x00772348  10 00 00 00 01 00 00 00 7c 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
0x00772398  14 00 00 00 01 00 00 00 7d 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
0x00779220  20 00 00 00 01 00 00 00 7e 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
0x00779280  30 00 00 00 01 00 00 00 7f 00 00 00 fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd




从上面可以总结以下几点:
【1】第一顺序的四个字节代表分配内存大小,并以小端(可能跟cpu有关,没在大端机器上验证,欢迎有大端机器的朋友验证)方式呈现,在32位处理器或者32位操作系统下,程序所能允许分配最大内存为2^32次幂;
【2】第二顺序的四个字节不清楚代表什么
【3】第三顺序的四个字节代表分配数据类型(注2)

7a--char
7b--short
7c--int
7d--long
7e--float
7f--double


至于还有结构体以及类的分配可能需要另外讨论

【4】第四顺序的四个字节都为fd,猜测默认为保留字节
对应不同结构体类型亦有不同值与之对应
疑问:如何从上面的资料计算申请分配内存的大小
我们知道了所分配内存个数在第一顺序的四个字节中有体现,但是所分配内存的单个单元大小几何单从第三顺序的四个字节看不出所以然。再分析下第三顺序的四个字节,对应【总结3】,略加分析,会发现单个单元大小也对应了某个值。我试了下不同结构体对应的值也各不一样。猜测vs编译器对其单个单元值在编译时进行了计算,以便于在释放内存时清楚该释放内存大小。

glibc分配内存

glibc则清晰很多,因为可以阅读源码,其在分配内存前增加了一个 HEADER_SIZE ,跟踪malloc函数实现可以发现
typedef struct header {
long check;
union {
struct header *next;
struct free_list *fl;
} u;
} *header_t;

#define HEADER_SIZE sizeof (struct header)

typedef struct free_list {
spin_lock_t lock; /* spin lock for mutual exclusion */
header_t head; /* head of free list for this size */
#ifdef DEBUG
int in_use; /* # mallocs - # frees */
#endif /* DEBUG */
} *free_list_t;

注1:这里写16byte是因为对比了分配内存首地址往前偏移8byte、16byte、32byte,发现16byte内存内容跟所分配的最接近,因为没有源码,所以只能做如上猜测

注2:没有实际资料证明,只是猜想,上面几个是基本数据类型,但是面对结构体或者类时其怎么表示尚不清楚
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: