鉴于网上这个资料实在太少,将以前整理过却未完全的一篇文章贴出来,希望大牛指正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. 《linux设备驱动开发详解》笔记——10中断与时钟

    10.1 中断与定时器 中断一般有如下类型: 内部中断和外部中断:内部中断来自CPU,例如软件中断指令.溢出.除0错误等:外部中断有外部设备触发 可屏蔽中断和不可屏蔽中断 向量中断和非向量中断,ARM ...

  2. SmartGit 30天评估期结束解决办法

    smartgit 需要输入序列号解决办法: 1.找到路径: %APPDATA%\syntevo\SmartGit\<main-smartgit-version> 然后删除: setting ...

  3. selenium2 页面对象模型Page Object

    开发Selenium WebDriver测试时,可以使用页面对象模型,这样可使得测试脚本有更高的可维护性,减少了重复的代码,把页面抽象出来.同时页面对象模型也提供了一个注释,帮助缓存远程,避免出现元素 ...

  4. Monkeyrunner 简介及其环境搭建

    Monkeyrunner是通过坐标.控件ID和控件上的文字操作应用的界面元素,其测试用例是用python写的,这样就弥补了monkey只有简单命令无法执行复杂用例的缺陷.Monkeyrunner采用的 ...

  5. Hadoop4.2HDFS测试报告之二

    第一组:文件存储写过程记录 测试系统组成 存储类型 测试程序或命令 测试文件大小(Mb) 文件个数(个) 客户端并发数(个) 写速率(M/s) NameNode:1 DataNode:1 本地存储 s ...

  6. UVa 11695 树的直径 Flight Planning

    题意: 给出一棵树,删除一条边再添加一条边,求新树的最短的直径. 分析: 因为n比较小(n ≤ 2500),所以可以枚举删除的边,分裂成两棵树,然后有这么一个结论: 合并两棵树后得到的新树的最短直径为 ...

  7. spring boot 启动慢的原因

    停留在Spring logo那里差不多4分钟 SpringBoot启动慢的原因应该是某些应用占用了spring config server默认的端口8888,然后SpringCloud进程有些引用了s ...

  8. hibernate源码分析1-保存一个对象

    要点 用了event的方式贯穿CRUD的过程 值得学习 用dynamic-insert 支持 插入时 可选 全字段插入 还是仅仅有值的字段插入. 返回主键的值 用了 Serializable 类型作为 ...

  9. 添加字段的SQL语句的写法:

    alter table [表名] add [字段名] 字段属性 default 缺省值 default 是可选参 --删除字段   -- alter table  [SolidDB].[dbo].tP ...

  10. (英文排版测试)Lorem Ipsum

    Lorem Ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis tincidunt consequat pretiu ...