malloc之动态内存分配初探
Posted dengqiangjiayou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了malloc之动态内存分配初探相关的知识,希望对你有一定的参考价值。
动态内存分配初探
内存分配有定长内存分配也有动长内存分配,2者各有优缺点,前者寻址的时间复杂度O(1),后者O(n),对于实时性比较高的场景来说很明显前者比较适合,且前者不易造成内存碎片化,后者则更灵活,想要多少就分多少,比较能节省内存。
内存碎片化,也就是很难申请到一段连续的堆空间(比如数组),目前博主知道的解决方法可以通过单链表或者双向链表的方式把这些碎片的内存连起来,而又是由于链表的弊端,造成这部分寻址时间会比较长,所以有些设备如果不重启的话会越用越卡,这可能是原因之一。
那定长内存分配,定多长? 看以下代码:
int* p1 = (int*)malloc(sizeof(int) * 4);
int* p2 = (int*)malloc(sizeof(int) * 8);
int* p3 = (int*)malloc(sizeof(int) * 12);
int* p4 = (int*)malloc(sizeof(int) * 17);
int* p5 = (int*)malloc(sizeof(int) * 19);
int* p6 = (int*)malloc(sizeof(int) * 1);
int* p7 = (int*)malloc(sizeof(int) * 2);
int* p8 = (int*)malloc(sizeof(int) * 3);
char* p9 = (char*)malloc(sizeof(char) * 1);
char* p10 = (char*)malloc(sizeof(char) * 2);
char* p11 = (char*)malloc(sizeof(char) * 3);
printf("p1 addr is %x\\n",p1);
printf("p2 addr is %x\\n",p2);
printf("p3 addr is %x\\n",p3);
printf("p4 addr is %x\\n",p4);
printf("p5 addr is %x\\n",p5);
printf("p6 addr is %x\\n",p6);
printf("p6 addr is %x\\n",p7);
printf("p8 addr is %x\\n",p8);
printf("sizeof(int) is %d\\n",sizeof(int));
printf("---------------------\\n");
printf("p9 addr is %x\\n",p9);
printf("p10 addr is %x\\n",p10);
printf("p11 addr is %x\\n",p11);
p1->p2: 4*16byte = 64byte p1开始申请了16byte的数据
p2->p3: 4*16byte = 64byte p2开始申请了32byte的数据
p3->p4: 6*16byte = 96byte p3开始申请了48byte的数据
p4->p5: 8*16byte = 128byte p4开始申请了68byte的数据
p5->p6: 8*16byte = 128byte p5开始申请了76byte的数据
p6->p7: 4*16byte = 64byte p6开始申请了4byte的数据
p7->p8: 4*16byte = 64byte p7开始申请了8byte的数据
char
p8->p9: 4*16byte = 64byte p8开始申请了12byte的数据
p9->p10: 4*16byte = 64byte p9开始申请了1byte的数据
p10->p11: 4*16byte = 64byte p10开始申请了2byte的数据
由以上分析可见:
定长申请一次申请 64 byte,也就是从一开始的地址处,+63都是有效的,+ 到第64位时应该会报错,所以下面做一个测试
果然*(p11+64)后就直接报错了,去掉*(p11+64)就又好了
正确,从打印的结果及之前的积累又可以得知:除了静态区的变量被编译器初始化为0外,其他区域的都是随机值
所以不管大小都是分配随机值看起来很浪费,那如何不定长分配呢?
请看下回分解
以上是关于malloc之动态内存分配初探的主要内容,如果未能解决你的问题,请参考以下文章