Memory Management文档格式.docx
- 文档编号:16798428
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:11
- 大小:50.16KB
Memory Management文档格式.docx
《Memory Management文档格式.docx》由会员分享,可在线阅读,更多相关《Memory Management文档格式.docx(11页珍藏版)》请在冰豆网上搜索。
1.6.1.檢查內存泄漏7
1.6.2.檢查內存重復釋放7
1.6.3.檢查內存越界7
1.6.4.避免在棧中分配過大內存8
1.6.5.注意對指針的使用9
1.6.6.多線程模式下的內存問題10
1.6.7.理解幷遵守平臺(如obigo,OP,BREW)的內存使用原則11
1.简介
1.1.文檔使用者
1.2.参考
本文参考了如下的文档,各个参考文档使用[x]来标记。
1.3.缩略词
1.4.问题报告
有任何关于此文档的问题,请报告给allenq@。
内存和指针的使用和管理是c开发大型项目最重要的内容之一。
不少大型项目的失败都是大量的内存和指针使用不当引起。
下面介绍多线程ui情况下内存模型和使用注意事项。
1.5.内存模型
目前嵌入式的线程模型是单进程多线程的模式。
在这种模式下,内存模式如下
内存分为四大类
●代码段,放置所有的代码
●全局数据段放置全局数据和静态数据,所有线程共享全局数据段
●堆,放置动态分配的内存,所有线程共享堆
●栈,放置线程的局部变量,不同线程有不同的栈
intg_var1;
char*g_var3;
func1()
{
staticdoubles_cc=0;
intf1_var1;
char*f1_var2=malloc(10);
func2();
}
func2()
charf2_var2;
f2_var2++;
g_var3=malloc(10);
假定当前有两个task,task1&
task2
task1调用func1并且运行到了func2的g_var3=malloc(10)代码处
task2调用func1并且运行到了func1的char*f1_var2=malloc(10);
函数处
此时,线程模型如下图
1.6.内存管理原则
内存引起的bug,特定如下
1不会马上引起错误,但以后不确定的某种情况下可能发生错误,而且该错误与诱发错误的地方几乎看不出任何联系
2一旦发生错误,都是致命错误,导致系统crash
3debug非常麻烦
所以”内存使用不当”是用c/c++开发大型项目中最重要的bug之一,尤其经验不是非常丰富的工程师,最容易犯这类错误(其实经验比较丰富的工程师也会犯这类错误)。
如果相当一部分工程师不注意内存使用,在很多地方写的代码都有内存错误,但这些错误只在特定条件下爆发,因此最初从表面上看,系统运行还算正常。
但当这些错误累加到一定程度,对系统的危害是非常大的。
因此建议所有的工程师都重视内存使用,养成内存检查的习惯
建议每写完/修改完一个函数,都按照以下流程检查错误
1.6.1.检查内存泄漏
内存泄漏就是,对于动态分配的内存,没有释放
如果写了以下代码
char*pStr=mfw_alloc(10)
mfwHndtim=timCreate();
对应在函数结束前,就应该释放内存
mfw_free(pStr,10)
timDelete(tim)
1.6.2.检查内存重复释放
对已经释放的内存再次释放,就是重复释放
如
…..
…….
mfw_free(pStr,10)//内存重复释放,可能造成内存错误
1.6.3.检查内存越界
3.1避免数组越界
如intnNum[10]
要确认各种情况下,不可以访问内存nNum[n]n>
=10
比较良好的习惯是用宏来防治越界
如#defineMAX_NUM10
intnNum[MAX_NUM]
for(intI=0;
I<
MAX_NUM;
I++)
访问nNum;
3.2避免字符串越界
●理解c语言中字符串以’\0’(真0)结束,如果一个字符串中最大容纳10的字符,需要分配11个字符长度,如charcStr[MAX_LEN+1],最后一个字符放置’\0’
●分配字符串后,需要立刻把字符串置0
如charcStr[MAX_LEN+1];
memset(cStr,0,MAX_LEN+1)
否则,请看以下代码
inta=strlen(cStr);
此时a的数值不确定,很有可能大于MAX_LEN+1,如果在用a对cStr操作,后果非常严重
●理解所有字符操作函数,都是以’\0’为结束,如
chara[10]={'
1'
'
2'
3'
\0'
4'
};
此时数组中的内容为
31323300340000000000
⏹此时如果调用strlen(a),返回值为3,因为第四个字符为’\0’,第五个字符不予处理
⏹如果执行以下语句
charb[10],
memset(b,0,10)
strcpy(b,a);
此时b的内容为31323300340000000000,即只copy到a的第三个字符
charc[10]={'
strcat(ca);
此时c的内容为31323132330000000000
1.6.4.避免在栈中分配过大内存
我们开发的嵌入式软件,每个task的栈的大小都非常有限(目前mmitask的栈为6k).
栈的使用有以下特点。
●栈有迭加效果,
函数a在栈中分配了1k字节内存
函数b在栈中分配了1k字节内存
函数c在栈中分配了1k字节内存
只调用a|b|c都没有问题,但如果a调用b,b调用c,就可能出错
●一旦出错,非常非常难查
函数中的局部变量分配在栈中,一般来讲,如果一个局部变量大于100个字节,就应该动态分配
错误写法
intfunc1()
charb[100]//b占用100个字节的栈空间,可能诱发栈被破坏
正确写法
char*b=mfw_alloc(100);
1.6.5.注意对指针的使用
对指针的使用规则如下
●初始化为0
●分配一块空间,指针指向该空间
●释放空间,指针重新指向0
代码事例
●初始化
char*pStr=0;
●分配空间
if(pStr==0)//pStr为0,表示其不指向任何动态内存,不要释放
pStr=mfwAlloc(10)
●释放空间
if(pStr!
=0)//pStr不为0,表示其指向动态内存,需要释放
mfwFree(pStr);
pStr=0;
这样我们可以掌握以下原则
●如果某指针为0,则该指针不指向任何动态分配内存。
⏹可以分配内存同时把首地址给该指针,而不会内存泄漏。
⏹如果该指针指向某动态分配内存,释放后该指针指向0,以后不需要再释放内存,防止内存重复释放
●如果某指针不为0,说明该指针指向动态分配内存
⏹如果需要分配内存同时把首地址给该指针,需要先释放该指针指向的原内存,否则会内存泄漏
⏹在离开该指针作用范围前,需要释放该指针指向的动态内存
1.6.6.多线程模式下的内存问题
下面举一个简单的例子说明线程同步,
对于线程不是很了解的同仁,建议还是读读其它相关数据,至少要理解相关基本概念,如线程和程序的关系等。
inttmp=0;
chartmpChar[10];
voidfunc1()
for(tmp=0;
tmp<
10;
tmp++)
tmpChar[tmp]=tmp;
voidfunc2()
……
tmp=20;
●如果这两个函数在同一个task里顺序执行,不会有问题
●假定func1由task1执行,func2由task2执行.如果func1先被运行,在运行到一半时(如tmp=5时),task1被中断,task2运行,给tmp赋值为20.然后task2休眠,task1接着运行,此时tmp=20,执行以下语句而内存越界
tmpChar[20]=20
这样的问题是比较难查的,可能大多数情况下task1和task2不会互相干扰,只是在特殊情况下才出现问题.
除了全局变量,凡是对所有线程都可见的存储空间(如堆内存和静态变量),都有上述问题。
请采取以下措施,避免多线程编程模式下的内存问题
●尽量避免使用全局变量和静态变量
●如果必须使用全局变量和静态变量,并且该全局变量和静态变量有可能被不同的线程访问,要用信号量等操作系统机制保护
●如果使用回调的方式实现功能,尽量在回调里面发送消息给另外一个线程,另外一个线程收到消息后实现该功能,而不要直接在回调函数里面写功能实现代码。
如线程A向线程B注册了一个回调函数,希望线程B发生特定事件后回调该函数实现某编码功能。
则最好不要在该回调函数里面实现编码功能,回调函数应该只是向线程A发送一个消息,线程A收到该消息后实现编码功能
1.6.7.理解幷遵守平台的内存使用原则
平台本身一般不会发生内存错误(否则该平台不会广泛使用),一般是我们对平台理解的不够透彻导致。
这样做看似比较麻烦,但是熟悉以后,其实非常快的。
同时基本把内存错误都避免了。
1.7.Referencecode
#include<
stdio.h>
intd;
printf("
dddddddd"
);
scanf("
%d"
&
d);
return0;
intfunc2();
string.h>
typedefint(*func)();
voidmem_override()
intarr[10];
memset(arr,0,sizeof(int)*10);
arr[10]=3;
return;
voidstr_len_test()
intstrLen=0;
{
charcStr[10+1];
strLen=strlen(cStr);
//ifyoucallstrcpy(cStr,str1,strLen);
willmemoryoverride
memset(cStr,0,10+1);
}
chara[10]={'
charb[10];
charc[10]={'
strLen=strlen(a);
memset(b,0,10);
strcpy(b,a);
strcat(c,a);
voidstack_override()
inttmp[10000000];
voidmain()
stack_override();
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Memory Management
![提示](https://static.bdocx.com/images/bang_tan.gif)