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

  • vs分配内存
vs没有源码,编译器在分配内存时,分配给用户的地址减去16个字节(注1),保存了分配内存的类型与大小
如下表示了vs编译器在分配内存时编译器的处理,代码如下:
 int _tmain(int argc, _TCHAR* argv[])
{
char *pcMem = (char *)malloc();
short *psMem = (short *)malloc();
int *piMem = (int *)malloc();
long *plMem = (long *)malloc();
float *pfMem = (float*)malloc();
double *pdMem = (double*)malloc(); system("PAUSE");
return ;
}
vs2008本地断点调试运行,对应地址分配如下
pcMem    0x007722c8 "屯屯屯屯铪铪"    char *
psMem 0x00772310 short *
piMem 0x00772358 int *
plMem 0x007723a8 long *
pfMem 0x00779230 float *
pdMem 0x00779290 double *
如下为pChar减去16个字节的地址内容
0x007722B8          7a    fd fd fd fd cd cd cd cd cd cd cd cd fd fd fd fd ab ab ab ab
0x00772300 0c 7b fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd fd fd fd fd
0x00772348 7c fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
0x00772398 7d fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
0x00779220 7e fd fd fd fd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd cd
0x00779280 7f 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:没有实际资料证明,只是猜想,上面几个是基本数据类型,但是面对结构体或者类时其怎么表示尚不清楚

free如何知道释放内存长度:vs与glibc分配内存时编译器内部处理的更多相关文章

  1. C++内存管理5-处理new分配内存失败情况(转)

    C++内存管理5-处理new分配内存失败情况(转) endl; 参考博客: https://www.cnblogs.com/findumars/p/9905195.html

  2. 浅析C++内存分配与释放操作过程——三种方式可以分配内存new operator, operator new,placement new

    引言:C++中总共有三种方式可以分配内存,new operator, operator new,placement new. 一,new operator 这就是我们最常使用的 new 操作符.查看汇 ...

  3. C++ 内存、new与malloc分配内存区别?

    一关于内存 1.内存分配方式 内存分配方式有三种: (1)从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. (2)在栈上创建. ...

  4. Delphi 的内存操作函数(2): 给数组指针分配内存

    静态数组, 在声明时就分配好内存了, 譬如: var   arr1: ..] of Char;   arr2: ..] of Integer; begin   ShowMessageFmt('数组大小 ...

  5. 使用 Lookaside List 分配内存

    1. 概述 windows 提供了一种基于 lookaside list 的快速内存分配方案,区别于一般的使用 ExAllocatePoolWithTag() 系列函数的内存分配方式.每次从 look ...

  6. Windows内存管理(1)--分配内核内存 和 使用链表

    1.      分配内核内存 Windows驱动程序使用的内存资源非常珍贵,分配内存时要尽量节约.和应用程序一样,局部变量是存放在栈空间中的.但栈空间不会像应用程序那么大,所以驱动程序不适合递归调用或 ...

  7. 20140319 const sizeof define 编译时分配内存

    1.面试宝典预处理,const,sizeof Define作用定义函数: //用一个宏定义FIND求一个结构体struc里某个变量相对于struc的偏移量,如FIND(student,a)//等于0 ...

  8. 【存储类、链接、存储管理】分配内存:malloc()、free()

    一.使用库函数:malloc()分配管理内存 (一)标识符(Identifier) 1. 定义变量时,使用了诸如 a.abc.mn123 这样的名字,它们都是程序员自己起的,一般能够表达出变量的作用, ...

  9. Java中对象在内存中的大小、分配等问题

    Java创建一个对象的过程 是否对象指向的类已经加载到内存了 如果没有加载,就要经过load.linking(verification.preparation.resolution).initiali ...

随机推荐

  1. [译]The Python Tutorial#6. Modules

    [译]The Python Tutorial#Modules 6. Modules 如果你从Python解释器中退出然后重新进入,之前定义的名字(函数和变量)都丢失了.因此,如果你想写长一点的程序,使 ...

  2. Python爬虫,爬取实验楼全部课程

    目的: 使用requests库以及xpath解析进行实验楼所有课程,存入MySQL数据 库中. 准备工作: 首先安装,requests库,lxml库,以及peewee库.在命令行模式,使用以下命令. ...

  3. linux的vi和vim编辑器操作

    vi:linux内部的文本编辑器:vim:vi的增强版,具有程序编辑的能力. vi和vim的三种常见模式: (1)正常模式(一般模式):vim一打开就是这种模式,此模式下可以使用各种快捷键,比如复制粘 ...

  4. dotnet core 运行程序注意事项

    .net core 程序 debug版本无法直接运行,因为没有相关的dll,只有在进入项目文件夹那一层,执行 dotnet run 来运行,会自动链接 当前用户的个人文件夹下的 .nuget/.pac ...

  5. 写iOS SDK注意事项

    转载http://www.devtang.com/blog/2015/01/31/write-sdk-tips/

  6. 总结:PHP值得注意的几个问题

    1.除了变量和常量区分大小写外,其他的标识符不区分大小写(例如关键字,类名,函数名等): 2. >>>是无符号右移,不管第一位是0还是1,右移后前面都是补0: 3.在函数中传递数组, ...

  7. windows :Tomcat免安装版环境变量配置 + jdk配置

    1.  下载后解压,我解压的目录为:D:\Tomcat\apache-tomcat-9.0.1-windows-x64 2.  安装jdk和jre, 并配置环境变量: 2.1 用户变量新建JAVA_H ...

  8. day01_06.比较运算符

    >  >=  =  <  <=  != == ===  !== 凡运算,必有运算结果,比较运算符的运算结果是布尔值 ==和===的区别 <?php $c = ( 3 == ...

  9. not exists、left join/is null、not in 行为

    测试数据 20:25:52[test](;)> select * from t;+------+------+| id   | b    |+------+------+|    1 | NUL ...

  10. JDBC 学习笔记(八)—— ResultSet

    JDBC 使用 ResultSet 来封装 SQL 的查询结果,可以将 ResultSet 类比为数据库表的查询结果. 它拥有如下两个性质: 可滚动. 可更新. 这两个性质,是在创建 Statemen ...