嵌软八股大全6 - C 内存
1、变量、代码内存分配
- 全局变量、静态变量 -> 数据区(.bss .data) ,未初始化时值为 0
- 局部变量 -> 栈区,未初始化时值为随机数
- 代码 -> 代码区
注意:
- 未显式初始化(未人为初始化)的全局变量和静态变量都将存放在 .bss 段
2、内存四区
- 栈区 -> 函数参数、局部变量,从高地址到低地址向下生长
- 堆区 -> 由用户自己分配内存,从低地址到高地址向上生长
- 数据区(.bss .data) -> 静态变量、全局变量
- 代码区 -> 可执行代码(程序代码指令、常量字符串等)
3、内存分配函数
- malloc -> 分配指定大小字节的内存块,但不初始化内存块的内容
- calloc -> 用于分配指定数量的内存块,并初始化内存块的内容为零
- realloc -> 用于调整之前分配的内存块的大小
- free -> 释放之前通过
malloc
、calloc
或realloc
分配的内存块
//头文件
#include <stdlib.h>
//从堆中申请 size 字节的内存
void *malloc(size_t size);
//从堆中申请 num 块 size 字节的内存,然后初始化内存块的内容为零
void *calloc(size_t num, size_t size);
//调整之前从堆中申请的内存的字节数为 new_size
void *realloc(void *ptr, size_t new_size);
//释放掉从堆中申请的内存
void free(void *ptr);
3.1、正确使用 malloc 函数的流程
首先包含头文件
#include <stdlib.h>
注意类型转换,malloc() 返回一个 void 指针,在使用时通常需要将其转换为所需类型的指针
//分配 4 字节内存
int *ptr = (int *)malloc(sizeof(int));
调用 malloc() 之后,应该检查返回值是否为 NULL
//如果分配失败,做出错误处理
if(ptr ** NULL)
{
printf("error\n");
}
使用完动态分配的内存后,应该及时释放内存,防止出现内存泄漏
//释放动态分配的内存
free(ptr);
4、内存常见问题
4.1、内存泄漏
4.1.1、定义
申请了内存,不使用之后并没有释放内存 or
指向申请的内存的指针指向了别的地方,导致找不到申请的内存
4.1.2、影响
程序运行时间越长,占用内存越多,最终用完内存,导致系统崩溃
4.1.3、如何处理
如果内存已经泄露,可以使用专门的工具(Visual Leak Detector)来检测内存泄漏,然后检查代码,确保所有动态分配的内存都得到了正确释放
如果内存尚未泄露,注意以下几条建议避免造成内存泄漏
- 良好的编码习惯
- 将分配的内存的指针以链表的形式自行管理
- 使用智能指针
- 使用常见插件
4.2、内存溢出
4.2.1、常见原因
- 动态申请空间使用之后没有释放
- 数组访问越界
- 指针非法访问
- 函数调用层次太深
4.2.2、strcat、strcmp、strcpy 哪些函数会导致内存溢出?
使用 strcat、strncat、strcpy、s
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
嵌入式软件名企笔/面试真题合集 文章被收录于专栏
欢迎来到我的专栏,在这里,我将整理并分享2024年各大企业的真实笔试/面试真题,同时还整理了嵌入式软件相关的八股知识。专栏内容涵盖C/C++基础、嵌软常见通信协议、ARM、FreeRTOS、Linux OS相关问题汇总,希望能帮助求职者了解考试趋势和嵌入式常见考点。无论你是准备面试,还是希望提升自己的专业知识,这里都能为你提供宝贵的参考和学习资源。