c语言内存对其和内存碎片问题

lihao0320 2012-07-17 08:47:20
加精
cpu使用stm32f107,编译用keil,网络应用,要求在网络不通的时候储存有效数据,到一定程度循环存放,释放最老的数据包……
当初考虑过使用数组解决,但是因为每包数据长度不固定,使用数组也不是一个很好的办法;而且储存的数据多的时候使用数组处理起来更麻烦;使用此种方法是否会造成内存碎片及内存耗尽的情况?
struct LNODE
{

u16 buflen; //包长度
u8 ref; //包标志,为1说明该包需要发送
struct LNODE *next; //下包地址
u8 *payload; //该包未发送数据指针
}
*not_sent_bufs;
//缓存链表首地址

链表节点如上,payload为不定长数据包指针,其长度为buflen,为了避免内存碎片,想创建节点时把payload数据内存一并申请,即malloc(sizeof(struct LNODE)+buflen);同时payload指向数据区头部;可否如此
not_sent_bufs = malloc(sizeof(struct LNODE)+buflen);
not_sent_bufs ->payload = (unsigned char *)not_sent_bufs +sizeof(struct LNODE); //
memcpy(not_sent_bufs ->payload,sbuf,buflen); //拷贝数据
……
加入节点到链表
……
...全文
4920 73 打赏 收藏 转发到动态 举报
写回复
用AI写文章
73 条回复
切换为时间正序
请发表友善的回复…
发表回复
nuaalyy 2012-11-08
  • 打赏
  • 举报
回复
给你点建议吧,看过一个开源库,觉得人家的内存处理真的不错,一开始直接用malloc申请一大段内存,做成一个缓冲池,另外做了一些接口对其进行管理,避免了频繁申请和释放内存,要知道,在循环中调用malloc时经常会出现很多问题如内存泄露和内存碎片,嵌入式中稳定性相当重要,宁愿内存使用率低一些,也要保持不能出错。 前面这两位说的也是这个道理,看来大家都是使用的一样的方法啊,哈哈
引用 60 楼 moneyjr 的回复:
看楼主的要求,无非就是一个RX Q 队列本身做成环形链表 然后内存管理用内存池,根据网络中最常见的包大小,可以建立若干个内存池。比如可以分为64字节、256字节、1024字节等等。 内存池所需空间直接用数组从数据区获得。 每个池中用一个数据结构维护可用的内存块数量等信息。
引用 56 楼 dthxman 的回复:
只要方法用对,根本不用担心碎片问题,前面的朋友说了,在运行中千万不要用malloc,太不稳定,建议你直接在启动时预留一块内存用作存放空间,当然能用flash那就更好了,完全不用担心不够的问题,然后针对你分配的一块内存,自己实现一套分配管理接口,例如mallocnet(),freenet(),原理可以参考slab的实现,完全自己透明实现小块内存的管理,分配和释放,链表最好是……
byeyear 2012-09-29
  • 打赏
  • 举报
回复
单个环形缓冲+固定长度数组(用来记录packet header信息)就足够了
RX Q都嫌麻烦
107最高等级也就64K内存 还不支持ExtMEM
protocol stack就得吃掉1/3内存吧
cxiaoxiangzi 2012-09-28
  • 打赏
  • 举报
回复
受教了,今天逛论坛收益不小。csdn支持
bigbat 2012-07-26
  • 打赏
  • 举报
回复
嵌入式内存的管理比较复杂,建议一次分配足够的内存不要图省点空间吧程序复杂化。想使用链表等结构也可以将协议层做成不同的数据结构体,再根据需要组合成一个包体。看看开源TCP协议栈会有所启发的。
solomoni0999 2012-07-26
  • 打赏
  • 举报
回复
c语言果真是比较高效的编程语言呀
roadinfo 2012-07-26
  • 打赏
  • 举报
回复
[Quote=引用 46 楼 的回复:]

引用 28 楼 的回复:

各种不明白,不明白搂主说什么,不明白为什么动态分配,不明白搂主的包为什么不发出去,不明白搂主怎么会产生内存泄露,总之各种不明白

我也是。。。
[/Quote]我也是
wgzh1615 2012-07-26
  • 打赏
  • 举报
回复
看来要学的还很多啊,不过还是喜欢c
daviddb7 2012-07-25
  • 打赏
  • 举报
回复
看楼主的要求,无非就是一个RX Q
队列本身做成环形链表
然后内存管理用内存池,根据网络中最常见的包大小,可以建立若干个内存池。比如可以分为64字节、256字节、1024字节等等。
内存池所需空间直接用数组从数据区获得。
每个池中用一个数据结构维护可用的内存块数量等信息。

「已注销」 2012-07-25
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 的回复:]

产生内存碎片是难免的,这涉及到windows内部内存管理的问题
[/Quote]看到这个,我,我,我,,,,keil,芯片stm32f107,windows,,,天,杀了我吧
xiaoshahai 2012-07-25
  • 打赏
  • 举报
回复
学习了,呵呵
moneyjr 2012-07-25
  • 打赏
  • 举报
回复
看楼主的要求,无非就是一个RX Q
队列本身做成环形链表
然后内存管理用内存池,根据网络中最常见的包大小,可以建立若干个内存池。比如可以分为64字节、256字节、1024字节等等。
内存池所需空间直接用数组从数据区获得。
每个池中用一个数据结构维护可用的内存块数量等信息。
moneyjr 2012-07-25
  • 打赏
  • 举报
回复
看楼主的要求,无非就是一个RX Q
队列本身做成环形链表
然后内存管理用内存池,根据网络中最常见的包大小,可以建立若干个内存池。比如可以分为64字节、256字节、1024字节等等。
内存池所需空间直接用数组从数据区获得。
每个池中用一个数据结构维护可用的内存块数量等信息。
dthxman 2012-07-24
  • 打赏
  • 举报
回复
只要方法用对,根本不用担心碎片问题,前面的朋友说了,在运行中千万不要用malloc,太不稳定,建议你直接在启动时预留一块内存用作存放空间,当然能用flash那就更好了,完全不用担心不够的问题,然后针对你分配的一块内存,自己实现一套分配管理接口,例如mallocnet(),freenet(),原理可以参考slab的实现,完全自己透明实现小块内存的管理,分配和释放,链表最好是双向的,用list_head,可以实现。
犇犇犇程序猿 2012-07-24
  • 打赏
  • 举报
回复
不知道你们的产品有没有FLASH存储,存储在外部空间更好
犇犇犇程序猿 2012-07-24
  • 打赏
  • 举报
回复
按楼主的思路,妥妥的,一个队列就搞定了啊,定长数组,定义一个协议,1字节标识数据包标志,2字节标识长度,再跟着数据包,最后2字节CRC验证码,100%不会出错。100%不会有什么数据遗漏。具体的小细节就不说了,我们的产品就这么搞的。
jxhqb 2012-07-23
  • 打赏
  • 举报
回复
可以考虑一下环形队列
dfasri 2012-07-23
  • 打赏
  • 举报
回复
看看MFC程序编程吧, 里面就有一个简单的内存池的实现方式, 想要不产生任何内存碎片很简单的, 只要每次分配的大小都跟页面大小一至, 这样就不会有碎片了. 创建出来的大块数据之后, 再划分成对应大小的每个小块, 连接起来成为Free链表, 申请时只要向Free链表查找有没有可用内存块, 有就直接返回, 没有就创建一个新的大块.
内存池的方式都基本是这样子的.

例子里面也是说明了固定长度的内存池, 要做成非固定长度的内存池, 很简单的, 仅需要加个HASH表, HASH就直接用申请的大小作为KEY即可.
每个HASH都保存着对应的Free链表, 那么申请动态内存的时候, 仅需要查找HASH表, 找到对应的FREE链表, 为空时, 就创建一个大块, 并且把划分出来的所有小块加入当前KEY的Free链表即可.

这个就是基础型的内存池了.

然后可以加入多一点的统计算法, 或者是直接加入固定的算法, 让经常使用的内存大小尽量减小释放所对应的内存块, 这样就可以提高不少速度了.
blueink_200451 2012-07-23
  • 打赏
  • 举报
回复
[Quote=引用 46 楼 的回复:]

引用 28 楼 的回复:

各种不明白,不明白搂主说什么,不明白为什么动态分配,不明白搂主的包为什么不发出去,不明白搂主怎么会产生内存泄露,总之各种不明白

我也是。。。
[/Quote]
+1
cc370102 2012-07-23
  • 打赏
  • 举报
回复
不能忘记 FREE
mimixi666 2012-07-22
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 的回复:]

各种不明白,不明白搂主说什么,不明白为什么动态分配,不明白搂主的包为什么不发出去,不明白搂主怎么会产生内存泄露,总之各种不明白
[/Quote]
我也是。。。
加载更多回复(29)

21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧