高级编程学习笔记(一) malloc的分配方法

来源:互联网 发布:中国进出口商品数据 编辑:程序博客网 时间:2024/05/21 19:33

原地址:http://blog.csdn.net/a8887396/article/details/8963907


1 linux 对内存的结构描述

/proc/${pid}/ 存放进程运行时候的所有信息(包括内存结构)
ps aue 查看pid
进入这个目录

cat maps 


由于当进程存在时那个pid文件夹才存在,所以你需要写一个死循环保证程序一直在运行

[cpp] view plaincopy
  1. #include <unistd.h>  
  2. #include <stdio.h>  
  3. int main()  
  4. {  
  5.     printf("%d\n",getpid());  
  6.     while(1){}  
  7. }  


2.理解malloc的工作的原理

malloc实际上使用一个数据结构(链表)维护分配的空间,
链表的构成: 分配的空间(n)/上一个空间指针(4)/下一个空间指针(4)/空间大小(4)
计算占用空间大小要采用对齐
对malloc分配的空间不要越界访问,因为容易破坏后台维护结构

导致malloc/free/callo/realloc不正常工作

这就是为什么连续使用 malloc 分配的首地址 之间的间隔不等于分配的空间大小的原因.

这就是为什么动态分配的空间, 越界修改后,会导致malloc/free/callo/realloc不正常工作的原因,


示例: 发现每个地址之间相差16. new的情况和这样一样

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. int main()  
  5. {  
  6.     int *p1 = (int *)malloc(4);  
  7.     int *p2 = (int *)malloc(8);  
  8.     int *p3 = (int *)malloc(16);  
  9.     int *p4 = (int *)malloc(8);  
  10.     int *p5 = (int *)malloc(8);  
  11.     int *p6 = (int *)malloc(4);  
  12.     int *p7 = (int *)malloc(4);  
  13.       
  14.     printf("%p\n",p1); //  %p输出地址,   %x 输出16进制,后面只能是整形  
  15.     printf("%p\n",p2);  
  16.     printf("%p\n",p3);  
  17.     printf("%p\n",p4);  
  18.     printf("%p\n",p5);  
  19.     printf("%p\n",p6);  
  20.     printf("%p\n",p7);  
  21.       
  22.     /* 
  23.     0x881b008 
  24.     0x881b018 
  25.     0x881b028 
  26.     0x881b038 
  27.     0x881b048 
  28.     0x881b058 
  29.     0x881b068 
  30.     */  
  31. }  


示例: 越界赋值后出现错误 

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4.   
  5. main()  
  6. {  
  7.     int* p1 =(int*)malloc(4);  
  8.     int* p2 =(int*)malloc(16);  
  9.     int* p3 =(int*)malloc(4);  
  10.       
  11.     *p1 =1;  
  12.     *(p1+1)=2;  
  13.     *(p1+2)=3;  
  14.     *(p1+3)=4;  
  15.     *(p1+4)=5;  
  16.     *(p1+5)=6;  
  17.     *(p1+6)=7;  
  18.     *(p1+7)=8;  
  19.     printf("*p2:%d\n",*p2); //5   
  20.     //free(p1); // 会出严重问题  
  21.     /* 
  22.     堆的结构: 
  23.     1 指向本空间的指针 
  24.     2 指向上一个空间的指针 
  25.     3 指向下一个空间的指针 
  26.     4 本空间的大小 
  27.     */  
  28. }  
这是因为修改了结构体里面的其它部分的值.



3 c++的new 和 malloc的关系
对应关系:
malloc new new[ ]
realloc new(void *p)  定位分配  在已有的空间上重新分配
calloc new[ ]
free delete delete[]


[cpp] view plaincopy
  1. #include <stdio.h>  
  2.   
  3. #include <new>  
  4.   
  5. int main()  
  6. {  
  7.     int a[20];  
  8.     int *p = new(a) int// 定位分配运算符  
  9.       
  10.       
  11. }  




结论:new的实现使用的是malloc
区别:new使用malloc以后初始化空间
(基本类型:初始化成默认值。自定义类型:调用构造函数)


delete 调用free实现的
delete 先调用析构函数再调用free


new与new[]的区别:
new只调用一个构造器分配和初始化
new[] 循环对每个构造器分配和初始化


delete与delete[]的区别:
delete只调用一个构造器析构和释放
delete[] 循环对每个构造器析构和释放
0 0