为何运行C程序时内存占用无变化?
问题:malloc分配内存后,任务管理器/free看不到内存占用变化
问题场景
我写了一个C程序,通过命令行参数指定内存大小,用malloc分配对应内存后循环遍历数组30秒,但不管是Windows任务管理器还是Linux的free工具,都看不到程序的内存占用有变化。后来发现是缺失一行计算数组元素个数的代码,导致分配的内存根本没被实际初始化,补上后问题就解决了。
原因分析
这是C语言初学者很容易踩的一个坑,核心在于虚拟内存和物理内存的区别:
malloc(b)只是向操作系统申请了一块虚拟内存地址空间,此时操作系统并没有真正把物理内存分配给你的程序- 只有当你的程序实际访问(读/写)这块虚拟内存时,操作系统才会触发"缺页中断",把对应的物理内存分配给程序,这时你才能在系统工具里看到内存占用变化
你之前缺失了c=b/4;这行代码,变量c的初始值是0,导致循环for(i=0;i<c;i++)完全不会执行——程序从来没碰过malloc分配的内存块,自然不会触发物理内存分配,系统工具里就看不到内存占用的变化。
代码修正与验证
补上c=b/4;后,c就被计算为数组的元素个数(因为int类型占4字节,总字节数b除以4就是元素数量),循环会遍历整个数组并给每个元素赋值num[i]=i,这就触发了物理内存的实际分配,此时再看任务管理器或free工具,就能看到程序的内存占用符合你指定的大小了。
修正后的完整代码:
#include<stdio.h> #include<stdlib.h> #include<time.h> int main(int argc, char* argv[]) // 获取命令行传入的内存大小(MB) { int d=atoi(argv[1]), b=0, c=0, i=0; // 将参数转为整数 b=d*1024*1024; // 把MB转换为字节数 c=b/4; // 计算数组元素个数(int占4字节) printf("value passed to array size\n- %d",b); // 打印要分配的总字节数 int *num = (int *)malloc(b); // 分配b字节的内存 time_t sec = 30; // 设置循环时长为30秒 time_t startT=time(NULL); while (time(NULL) - startT < sec) { for(i=0;i<c;i++) // 遍历数组并赋值,触发物理内存分配 { num[i]=i; } } free(num); // 补充:释放内存,避免内存泄漏 return 0; }
额外提醒
- 记得在程序结束前用
free(num);释放内存,避免内存泄漏 - 如果只是读未初始化的内存(比如
printf("%d", num[i]);),同样会触发物理内存分配,但未初始化的内存值是随机的,不建议这么做 - 不同系统下
int的字节数可能有差异,更严谨的写法是用sizeof(int)代替硬编码的4,比如c = b / sizeof(int);
内容的提问来源于stack exchange,提问作者0x13
相关产品推荐
相关产品推荐

