本帖最后由 蓝烟清 于 2011-12-31 16:31 编辑
这几天一直很郁闷,游戏老跳出,无任何提示。找了很久,原来是链表释放内存的问题,很不解,先给源码(在JY_PicInit函数)
清除表面内容- //如果链表不为空,删除全部链表
- list_for_each_safe(pos,p,&cache_head){
- struct CacheNode *tmp= list_entry(pos, struct CacheNode , list);
- int picid = tmp->id;
- int fileid = tmp->fileid;
- if(tmp->s!=NULL)
- SDL_FreeSurface(tmp->s); //删除表面
- list_del(pos);
- SafeFree(tmp);
- }
复制代码 清除pic内存- for(i=0;i<PIC_FILE_NUM;i++){
- pic_file[i].num =0;
- SafeFree(pic_file[i].idx);
- SafeFree(pic_file[i].grp);
- SafeFree(pic_file[i].pcache);
- if(pic_file[i].fp){
- fclose(pic_file[i].fp);
- pic_file[i].fp=NULL;
- }
- }
复制代码 很关键的一点:在清除PIC内存的时候,没有循环pcache进行free
或许有人认为在清除表面的时候已经SafeFree(tmp);,但是实际上并没有
可以把内容再打印出来- //如果链表不为空,删除全部链表
- list_for_each_safe(pos,p,&cache_head){
- struct CacheNode *tmp= list_entry(pos, struct CacheNode , list);
- int picid = tmp->id;
- int fileid = tmp->fileid;
- if(tmp->s!=NULL)
- SDL_FreeSurface(tmp->s); //删除表面
- list_del(pos);
- SafeFree(tmp);
- if(pic_file[fileid].pcache && pic_file[fileid].pcache[picid]){
- JY_Debug("list free cache %d fileid=%d failed", picid, fileid);
- }
- }
复制代码 在debug.txt就会看到这样类似的东西
11:46:45 list free cache 36 fileid=0 failed
11:46:45 list free cache 76 fileid=0 failed
11:46:45 list free cache 1157 fileid=0 failed
11:46:45 list free cache 1622 fileid=0 failed
11:46:45 list free cache 1181 fileid=0 failed
11:46:45 list free cache 1151 fileid=0 failed
11:46:45 list free cache 1143 fileid=0 failed
说明实际上在清除链表的表面内容时,并没有把pache同时删除。
我是这样理解的
这样就会造成在切换场景(JY_PicInit函数在每切换一次场景时就调用)的时候,不断的造成内存泄漏,而且经过测试,cache下挂的Surface也没有被清除
不知道理解对不对
还有一点
if(tmp->s!=NULL)
SDL_FreeSurface(tmp->s); //删除表面
应该也要改成
if(tmp->s!=NULL) {
SDL_FreeSurface(tmp->s); //删除表面
tmp->s = NULL; //避免野指针
}
List的作用是为了防止Surface过多,造成内存消耗过大。 但是遍历清空时这个为什么清不掉,原因为何,搞不明白啊
|