打印
[应用方案]

容易造成单片机内存溢出的几个陷阱

[复制链接]
2150|46
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chenci2013|  楼主 | 2024-2-22 23:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
总结一下关于程序的变量,和内存方面的概念,虽然是属于C语言方面非常基础的知识,但是工作中一不小心还是会发生一些内存泄漏、内存溢出之类的问题。所以自己对这块的理解也还远远不够。在这总结一下关于这方面的知识点,用来互相学习,更用来提醒自己,并作为自己的一个经验总结。

我们知道我们的程序一般是储存在flash里面的,但是运行的时候是在内存(RAM)里运行的,我们的程序一般有这么几个部分组成:宏定义、变量、常量、动态区、程序代码。

我们通过下面这个Demo程序来了解一下程序在运行的时候,这些部分大概都在内存中的哪些地方。

#define OFF 0x00          //宏定义不占用内存空间,宏在预处理阶段会被替换掉,执行文件中并不存在宏定义.
float Num = 3.14;         //全局变量,存在于“变量区”
char* str = NULL;         //全局变量,存在于“变量区”
int main()
{
     int time;               //局部变量,存在于“栈区”
     char* path = "C:\\Users";   //字符串常量,存在于“常量区”
     int Users_Num[8];       //局部变量,存在于“栈区”
     srt = (char*)malloc(10);    //申请动态存储区,存储于“堆区”
     static flaot con = 1.0;   //静态局部变量,存在于“变量区”

     //程序代码区
   delay_ms(time);                  //time未初始化,该变量为垃圾值
   strcap(str,"Hello World");   //字符串“hello World”比str申请的内存空间大,造成访问越界
   free(str);                        //释放str内存
   str = NULL;                    //使str指针指向空地址,方便下次使用
}
访问越界:
Demo程序上的strcap()语句出现后面字符串大小比前面str变量申请的空间内存大小大的情况就会出现访问越界的情况。写程序时尤其要关注那个字符串它到底有多长,一定要去留意一下。如果出现访问越界的问题有些编译器是可能识别不出来的,但确实会造成这个内存访问错误,除此之外还有一些类似的:比如像sprintf(),strcat()等函数都有可能会导致访问越界的情况发生。

还有就是数组,数组也是特别容易造成访问越界的,有些编译器可能会检测数组长度是否超出数组下标长度,但有的地方未必就能检测出,如将数组在for()循环里访问的,这个时候就需要注意了,千万小心不要让它出现访问越界的情况。因为编译是检测不出来的,但是在运行的时候就会出现内存访问的故障了。

栈区:
根据上面Demo程序写的我们知道局部变量是存在于“栈区”的,所以一般我们的局部变量通常不要定义的太大,尤其是一些数组变量,如果说非常大,就会占用非常大的栈区空间,那么这在程序运行的时候非常容易出现栈溢出。平常我们程序里不可避免的会调用一些函数,所以我们调用一些函数的时候最好不要有深层次的调用,因为在调用函数的过程中栈区会不停的存储函数相关的一些变量和一些地址。所以需要深层次的函数递归调用的时候,大家尽量采用别的方式去代替。

堆区:
当申请了动态区域,用完的时候一定要记得释放(free),如果没有释放,那么这块内存区域就将处于不可用状态(就像占着茅坑不拉屎一样),程序大了或运行久了就极有可能会导致内存的泄露(重启一下就能解决90%的问题根源),同时我们在释放的时候也要注意释放的内存只能释放一次,不要重复的释放,有的时候代码量会比较大,所以有可能会在不止一处地方进行了代码的释放操作。因为我们内存释放了一次后,该内存区域就有可能用来做别的事了,如果这时候我们又再释放一遍就很有可能会出现问题了。释放完之后最好把指针指向空地址,避免下次再使用指针的时候出现地址的错误。

以上都是我们平时在开发的过程中需要格外注意的。有了这么一个概念之后再写代码或者在规划代码的时候,心里能够有个数,我们知道这些东西都大概在内存的哪个地方,这样就会尽量的去避免出现内存溢出或泄露的问题。也能够提高我们代码的效率。

像关于程序变量和内存分配,都是需要我们时刻关注的问题。我相信有不少人在这块犯过很多的错误,也可能说明我们基础不够扎实,编写程序的习惯也不够好。

使用特权

评论回复
沙发
yorkbarney| | 2024-3-1 22:01 | 只看该作者
如果循环中的数组访问超出了数组的界限,就会尝试访问不属于数组的内存区域,导致内存溢出。

使用特权

评论回复
板凳
saservice| | 2024-3-1 23:31 | 只看该作者
单片机程序中的函数递归调用层次过深,或者局部变量过多,超过了栈空间的大小,会导致堆栈溢出。

使用特权

评论回复
地板
burgessmaggie| | 2024-3-2 07:47 | 只看该作者
在C和C++等语言中,动态内存是通过malloc、calloc、realloc和free等函数管理的。如果这些函数使用不当,可能会导致内存泄漏或内存碎片,从而引发内存溢出。

使用特权

评论回复
5
abotomson| | 2024-3-2 11:15 | 只看该作者
当访问数组时,如果访问的索引超出数组边界,可能导致内存溢出。例如,当数组长度为10时,访问数组的索引11及更高索引会导致内存溢出。

使用特权

评论回复
6
abotomson| | 2024-3-2 16:42 | 只看该作者
如果使用了未初始化的内存变量或数组,其值可能是未知的,可能会在程序中无意中写入该内存区域,导致溢出。

使用特权

评论回复
7
jtracy3| | 2024-3-2 16:55 | 只看该作者
在RTOS或中断驱动的系统中,如果任务或中断处理函数设计不当,例如任务栈大小分配不足,或者中断服务程序(ISR)中执行了过多或复杂的操作,都可能导致内存溢出。

使用特权

评论回复
8
pl202| | 2024-3-2 17:07 | 只看该作者
在使用C语言进行单片机编程时,如果频繁申请动态内存(如使用malloc或calloc函数),而又没有及时释放(使用free函数),或者申请的内存块大于可用堆空间,都可能导致内存溢出。

使用特权

评论回复
9
sdCAD| | 2024-3-2 18:02 | 只看该作者
如果程序中分配的内存没有被及时释放,累积的内存泄漏会导致可用内存减少,最终可能引发内存溢出。确保在不再需要时释放内存是避免内存泄漏的关键。

使用特权

评论回复
10
uptown| | 2024-3-2 18:28 | 只看该作者
递归调用是一种常用的编程技巧,但如果递归调用的深度过大,可能会导致栈溢出。

使用特权

评论回复
11
macpherson| | 2024-3-2 22:27 | 只看该作者
在递归函数中,如果递归深度超过了单片机内存可以承受的范围,会导致栈溢出。

使用特权

评论回复
12
kmzuaz| | 2024-3-2 23:33 | 只看该作者
当程序试图访问数组之外的内存时,就可能发生数组越界。这通常是由于数组索引超出了其定义的范围。

使用特权

评论回复
13
bestwell| | 2024-3-3 08:43 | 只看该作者
单片机的RAM资源有限,过多的全局变量和静态变量会占用大量内存空间,尤其是在嵌入式系统中,可能会导致内存不足。

使用特权

评论回复
14
tabmone| | 2024-3-3 09:40 | 只看该作者
单片机中使用malloc、calloc等函数动态分配内存时,如果没有正确管理,也可能导致内存溢出。应该跟踪动态分配的内存,并确保在适当的时候释放它们。

使用特权

评论回复
15
timfordlare| | 2024-3-3 10:30 | 只看该作者
在使用动态内存分配(如malloc、calloc、realloc等函数)时,如果对内存空间的大小估计不准确,可能导致内存溢出。例如,当实际需要的内存空间大于分配的空间时,程序可能会尝试访问超出分配的内存区域。

使用特权

评论回复
16
hearstnorman323| | 2024-3-3 10:49 | 只看该作者
全局变量在程序的整个生命周期内都会占用内存,如果使用了过多的全局变量,可能会耗尽单片机的内存资源。

使用特权

评论回复
17
51xlf| | 2024-3-3 12:03 | 只看该作者
引入的外部库可能包含内存管理的bug或者不适用于当前硬件环境,这也可能导致内存溢出。在使用外部库时,应仔细阅读文档,并测试其在目标硬件上的表现。

使用特权

评论回复
18
maudlu| | 2024-3-3 13:11 | 只看该作者
使用了不恰当的数据结构或算法,导致内存使用效率低下,例如使用链表而非数组,或者使用了复杂度较高的搜索和排序算法。

使用特权

评论回复
19
ingramward| | 2024-3-3 13:39 | 只看该作者
缓冲区溢出是一个常见的问题。当向缓冲区写入数据时,如果没有正确检查缓冲区的大小,可能会导致缓冲区溢出,从而导致内存溢出。

使用特权

评论回复
20
bartonalfred| | 2024-3-3 13:50 | 只看该作者
单片机中,堆栈溢出是一个常见的问题。当函数调用层次过深或局部变量占用的堆栈空间过大时,可能会导致堆栈溢出。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

100

主题

6194

帖子

4

粉丝