您的位置:首页 > 编程语言

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

2013-12-30 14:20 302 查看

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

1 linux 对内存的结构描述

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

cat maps 

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

[cpp] view
plaincopy

#include <unistd.h>  

#include <stdio.h>  

int main()  

{  

    printf("%d\n",getpid());  

    while(1){}  

}  

2.理解malloc的工作的原理

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

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

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

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

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

[cpp] view
plaincopy

#include <stdio.h>  

#include <stdlib.h>  

  

int main()  

{  

    int *p1 = (int *)malloc(4);  

    int *p2 = (int *)malloc(8);  

    int *p3 = (int *)malloc(16);  

    int *p4 = (int *)malloc(8);  

    int *p5 = (int *)malloc(8);  

    int *p6 = (int *)malloc(4);  

    int *p7 = (int *)malloc(4);  

      

    printf("%p\n",p1); //  %p输出地址,   %x 输出16进制,后面只能是整形  

    printf("%p\n",p2);  

    printf("%p\n",p3);  

    printf("%p\n",p4);  

    printf("%p\n",p5);  

    printf("%p\n",p6);  

    printf("%p\n",p7);  

      

    /* 

    0x881b008 

    0x881b018 

    0x881b028 

    0x881b038 

    0x881b048 

    0x881b058 

    0x881b068 

    */  

}  

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

[cpp] view
plaincopy

#include <stdio.h>  

#include <stdlib.h>  

#include <unistd.h>  

  

main()  

{  

    int* p1 =(int*)malloc(4);  

    int* p2 =(int*)malloc(16);  

    int* p3 =(int*)malloc(4);  

      

    *p1 =1;  

    *(p1+1)=2;  

    *(p1+2)=3;  

    *(p1+3)=4;  

    *(p1+4)=5;  

    *(p1+5)=6;  

    *(p1+6)=7;  

    *(p1+7)=8;  

    printf("*p2:%d\n",*p2); //5   

    //free(p1); // 会出严重问题  

    /* 

    堆的结构: 

    1 指向本空间的指针 

    2 指向上一个空间的指针 

    3 指向下一个空间的指针 

    4 本空间的大小 

    */  

}  

这是因为修改了结构体里面的其它部分的值.

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

[cpp] view
plaincopy

#include <stdio.h>  

  

#include <new>  

  

int main()  

{  

    int a[20];  

    int *p = new(a) int; // 定位分配运算符  

      

      

}  

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

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

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

delete与delete[]的区别:
delete只调用一个构造器析构和释放
delete[] 循环对每个构造器析构和释放
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux 系统编程