免费域名网站黄的免费,网络设计项目,wap 网站模板,计算机网站开发1、内存的区域 对于内存的区域划分上#xff0c;不同的区域划分上都各有不同。 划分1#xff1a; 代码区、堆、栈、 全局区#xff08;静态存储区#xff09;、 文字常量区、 划分2#xff1a; 代码段、堆、栈、 data段、BSS段、文字常量区 全局区#xff1a; 又成为静…1、内存的区域 对于内存的区域划分上不同的区域划分上都各有不同。 划分1 代码区、堆、栈、 全局区静态存储区、 文字常量区、 划分2 代码段、堆、栈、 data段、BSS段、文字常量区 全局区 又成为静态存存储区。保存的是全局变量和静态变量带有static 关键字。全局区分为两个区域一个区域保存的是经过初始化且初始化的值不为零的全部变量和静态变量一个区域保存的是没有经过初始化或者初始化的值为零的。程序结束由 OS 进行释放 常量区 将一些不可以被更改的只读的常量进行保存的区域。比如文字字符串等。程序结束之后由系统释放。 代码区 保存的是二进制代码的区域。 堆 由程序猿手动 malloc/free进行开辟的空间一般也是由程序猿调用 free/delete 进行释放即使没有进行释放也可以由 OS 进行释放。 栈 程序运行的时候由编系统进行分配存在函数的的局部变量等。程序结束由系统自动释放。 DATA段 有经过初始化的全局变量和静态变量存储的区域当然初始值不能为零 BSS段 保存的是没有经过初始化的全局变量和静态变量存储的区域或者经过初始化但是初始值为零的也保存在这个区域。 注意很显然DATA 段和 BSS 段的也行其实就是全局区静态存储器内部之一DATA 段和 BSS 段只不过是全局区更加精细的划分。 解释 借助前人总结的知识 int a 0; 全局初始化区
char *p1; 全局未初始化区
main()
{ int b; // 栈 char s[] abc; //栈 char *p2; //栈 char *p3 123456; //123456/0在常量区p3在栈上。 static int c 0 //全局静态初始化区 p1 (char *)malloc(10); p2 (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。 strcpy(p1, 123456); // 123456 放在常量区编译器可能会将它与p3所指向的123456 //优化成一个地方。
} 2、内存的三种来源栈、堆、全局区 栈 1运行时候由编译器自动分配自动回收这一切都是自动的程序猿不用管理 2反复使用每一个进程操作系统都会为这个进程分配栈这个进程不论是怎么出入栈都是在这个栈反复使用。 3脏内存栈内存由于反复的使用程序使用完毕之后不会去做清理的工作所以重新使用栈的时候值就是脏的。 4临时性局部变量的出栈入栈每次都是不一样所以都是临时性的所以绝对不要返回栈变量的指针因为栈地址都是临时的 5栈溢出因为栈的大小是操作系统设定的当出现无线递归或者出现巨大的局部变量。 堆 1大块内存栈的空间非常有限所以当需要需要大块内存的时候就在堆进行申请 2手动申请、释放 使用 malloc/new 申请free/delete 进行释放。 3脏内存 : 堆内存也是被反复使用的 malloc 实际应用 操作系统会对空闲的内存块进行组织管理而这种组织管理的方式是以链表的形式。当程序猿调用 malloc 的时候就从空闲的链表找出一块大小满足申请要求的空间可以比用户申请的大然后将这个内存空间一分为二一部分是用户申请空间的大小另外的部分是维护链表这个节点的基本信息比如地址、块内存的大小。所以当 malloc 的时候不论申请的空间是多大都必须申请一块用于维护链表的空间。 #include stdio.h
#includestdlib.h
int main(void)
{int i,j;FILE * fp fopen(qxj511.txt, w);for ( i 0; i 2048; i){int *p1 (int *)malloc(i);int *p2 (int *)malloc(i);fprintf(fp, i %d : p1 %d, p2 %d,\n,i, p1, p2);free(p1);free(p2); }fclose(fp); /*关闭文件*/
} 在 gcc 的编译器下面做的测试 i 0 : p1 151765360, p2 151765376, // 1
i 1 : p1 151765376, p2 151765360,
i 2 : p1 151765360, p2 151765376,
i 3 : p1 151765376, p2 151765360,
i 4 : p1 151765360, p2 151765376,
i 5 : p1 151765376, p2 151765360,
i 6 : p1 151765360, p2 151765376,
i 7 : p1 151765376, p2 151765360,
i 8 : p1 151765360, p2 151765376,
i 9 : p1 151765376, p2 151765360,
i 10 : p1 151765360, p2 151765376,
i 11 : p1 151765376, p2 151765360,
i 12 : p1 151765360, p2 151765376, // 1
i 13 : p1 151765392, p2 151765416, // 2
i 14 : p1 151765416, p2 151765392,
i 15 : p1 151765392, p2 151765416,
i 16 : p1 151765416, p2 151765392,
i 17 : p1 151765392, p2 151765416,
i 18 : p1 151765416, p2 151765392,
i 19 : p1 151765392, p2 151765416,
i 20 : p1 151765416, p2 151765392,
i 21 : p1 151765440, p2 151765472,
i 22 : p1 151765472, p2 151765440, // 2
。。。。。。。 经过笔者的测试当 申请的的空间从零到12个字节的时候两者的差是16个字节后序申请的全部的空间差是 8 个字节。也就是说实际申请的空间是链表头部 申请的空间同时8 个字节是处于内存对齐。 参考 http://blog.csdn.net/misskissc/article/details/17717717 1malloc(0) : If size is 0, thenmalloc() returns either NULL, or a unique pointer value that can later be successfully passed to free(). 根据官方的解释当申请的空间为零的时候返回值要么是为 NULL要么就可以正确返回一个地址这个地址被正确释放。但是实际上都是返回后者。 根据 malloc 的实现方式虽然申请的空间为零但是链表的指针也是会被申请一段空间的所以可以正确申请空间为 16 字节maybe 8字节 0 而这个链表指针地址其实就是 malloc 的返回值的地址。 注意 对于链表维护空间的大小是16 字节这个是不确定的有人说是8个字节 malloc 与 sizeof 使用 malloc 是申请了一个程序猿指定的空间返回值是指向这段空间的的首地址。想要计算这段申请空间的大小是不可以通过 sizeof 计算出来的 int *p (int *)malloc(10 * sizeof(int));
printf(%d\n, sizeof(p)); 打印出来 等于4 原因分析p 是指向申请空间的首地址也就是说这个是地址对于指针来说不论指向的空间是多大指针占据的就是四个字节。所以sizeof 是不能计算 malloc。转载于:https://www.cnblogs.com/qxj511/p/4933705.html