堆内存的介绍及应用(含例子)

堆内存的介绍及应用(含例子)本文详细介绍了堆内存的概念 使用场景 管理机制以及常见问题

大家好,欢迎来到IT知识分享网。

一、什么是堆内存

二、为什么要使用堆内存

三、如何使用堆内存

  1. 例如:void *malloc(size_t size);
    功能:从堆内存中申请size个字节的内存,申请到内存中数据的值不确定
    返回值:成功返回申请到的连续内存的首地址,失败返回NULL

  2. void free(void ptr);
    功能:释放一块堆内存 ptr: 要释放的堆内存的首地址 注意:free释放只是使用权,数据不会全部清理 不能连续释放,但是可以释放NULL
  3. void *calloc(size_t nmemb,size_t size);
    功能:从堆内存申请nmemb块,每块size字节大小的内存 返回值:成功返回申请到的连续内存的首地址,失败返回NULL
    注意:calloc申请到的内存会被初始化为0,速度比malloc慢 short *p = calloc(10,4) == malloc(40)

  4. void realloc(void *ptr,size_t size);
    功能:改变已有的堆内存的大小,size表示调整后的大小,在原有的基础上调大调小
    返回值:调整后内存块的首地址,一定要重新接受返回值,可能不是在原位置进行调整 如果无法在原位置调整:
    1.申请一块新的符合大小的内存
    2.拷贝原内存中的数据
    3.释放原内存,返回新内存首地址




四、malloc的内存管理机制

  1. 当首次向malloc申请内存,malloc会向操作系统申请内存,操作系统会直接分配33页(1页=4096字节)内存
    malloc管理,但是并不意味着可以越界访问,因为malloc可能把其它的内存分配给‘其他人’,这样就会产生脏数据
  2. 每个内存块之间会有空隙(4~12字节),一部分空隙是为了内存对齐,其中一定有4字节记录了malloc的维护信息,这些维护信息决定了下一次malloc分配内存的位置,如果破坏了维护信息,会影响下一次malloc或者free的过程

五、使用堆内存需要注意的问题

内存泄漏:
内存无法在使用,也无法被释放,需要再次使用时只能重新申请内存,然后继续重复以上过程,日积月累后可用的内存越来越少
注意:一旦进程结束,属于该进程的所有资源都会被操作系统回收
如何尽量的减少内存泄漏:谁申请谁释放,谁知道该释放谁释放
如何判断、定位内存泄漏
1、查看内存使用情况
win 任务管理器
Linux ps -aux命令
2、借助代码分析工具 mtrace 检查malloc和free是否成对出现
3、封装malloc、free,记录申请、释放的信息到日记文件中








void *m_malloc(size_t size) { 
    s = malloc(size); fprintf("h%d malloc",filename); } void m_free(void *ptr) { 
    free(ptr); } 

内存碎片:
已经释放了但无法继续使用的内存叫做内存碎片,它是由于申请和释放的时间不协调导致的,无法完全避免,只能尽量减少
如何减少内存碎片的产生:
1、尽量使用栈内存
2、不要频繁地申请、释放内存
3、尽量申请大块内存,自己来管理




六、内存清理函数

七、堆内存定义二位数组

例子1:计算100~10000之间所有的素数,结果储存在堆内存中,尽量不要浪费内存

1、先计算有多少个、再一下全部申请出来

 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<stdbool.h> 4 bool math_is(int n); 5 6 int main() 7 { 
    8 int *s = NULL;//置空 9 int cnt = 0; 10 for(int i=100;i<=10000;i++) 11 { 
    12 if(math_is(i))//调用函数,判断是否是素数 13 { 
    14 cnt++; 15 } 16 } 17 s = malloc(4*cnt); 18 int j = 0; 19 for(int i=100;i<=10000;i++) 20 { 
    21 22 if(math_is(i)) 23 { 
    24 s[j] = i; 25 j++; 26 } 27 } 28 for(int i=0;i<cnt;i++) 29 { 
    30 printf("%d ",s[i]); 31 } 32 return 0; 33 } 34 35 bool math_is(int n) 36 { 
    37 38 for(int j=2;j<=n/2;j++) 39 { 
    40 if(n%j == 0) 41 { 
    42 return false; 43 } 44 } 45 return true; 46 47 } 

2、一边算,一边申请

#include<stdio.h> #include<stdbool.h> #include<stdlib.h> bool is_prime(int num) { 
    for(int i=2;i<=num/2;i++) { 
    if(0 == num%i)return false; } } int main() { 
    int *arr = NULL; for(int i=100;i<=10000;i++) { 
    if(is_prime(i)) { 
    arr = realloc(arr,sizeof(int)*(cnt+1)); arr[cnt++] = i; } } } for(int i=0;i<cnt;i++) { 
    printf("%d",arr[i]); } 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/131150.html

(0)
上一篇 2025-08-09 22:15
下一篇 2025-08-09 22:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信