免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 高峰
打印 上一主题 下一主题

大家在编程过程中有没有自己比较得意的代码,共享一下,我先来我的一个。 [复制链接]

论坛徽章:
0
41 [报告]
发表于 2007-08-16 20:19 |只看该作者
E*, 他的代码没有问题的,next是一个指针,存放的是下一个结点的值,
释放完之后再这样:
link=(void*)(*((long*)next));                                

不知道我的解释你清楚没有...总之,存放的只是指针,释放的是保存这个指针的空间,但是指针本身没有被释放.

论坛徽章:
0
42 [报告]
发表于 2007-08-16 22:50 |只看该作者
原帖由 converse 于 2007-8-16 20:19 发表
E*, 他的代码没有问题的,next是一个指针,存放的是下一个结点的值,
释放完之后再这样:
link=(void*)(*((long*)next));                                

不知道我的解释你清楚没有...总之,存放的只是指针,释 ...


还是converse瞬间就看懂了,呵呵.

不过,后面不要说"总之"就好了,哈哈

更重要的是释放指针所指的空间(包括了下一个节点的指针的本身的空间[4字节或8字节]).而不是"释放保存这个指针的空间".

怎么感觉这么扰啊.

[ 本帖最后由 高峰 于 2007-8-16 22:56 编辑 ]

论坛徽章:
0
43 [报告]
发表于 2007-08-16 22:52 |只看该作者
我的代码。 目前在我自己的项目里面用的。

创造了一个数组。 然后一次性申请一大块内存。 每次获取一块。 用完就放回。 可以避免不断new delete 造成虚拟存储变大。
   每次在内存块上有一个 struct 。包含了返回的信息。在用完的时候可以根据这个strcu 可以进行正确的放回。  代码的思想 copy 自apache 的apr lib. 不同的是它的块是动态大小。我是固定的。 (项目设计的)

论坛徽章:
0
44 [报告]
发表于 2007-08-16 22:57 |只看该作者
原帖由 benjiam 于 2007-8-16 22:52 发表
我的代码。 目前在我自己的项目里面用的。

创造了一个数组。 然后一次性申请一大块内存。 每次获取一块。 用完就放回。 可以避免不断new delete 造成虚拟存储变大。
   每次在内存块上有一个 struct 。包含 ...


能不能把关键部分展示一下?

论坛徽章:
0
45 [报告]
发表于 2007-08-16 23:02 |只看该作者
搜索以前的帖子,他发过完整的实现的。

论坛徽章:
0
46 [报告]
发表于 2007-08-16 23:06 |只看该作者
原帖由 benjiam 于 2007-8-16 22:52 发表
我的代码。 目前在我自己的项目里面用的。

创造了一个数组。 然后一次性申请一大块内存。 每次获取一块。 用完就放回。 可以避免不断new delete 造成虚拟存储变大。
   每次在内存块上有一个 struct 。包含 ...


mark一个 我回头看看.

另外, E*还是对这个代码有疑问,也提出了疑点,我现在还得回头再认证一下,后面给个答复.

论坛徽章:
0
47 [报告]
发表于 2007-08-16 23:14 |只看该作者
E*的问题出来了,我觉得他是对的.

看看代码吧:


  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. typedef struct linktype_s
  4. {
  5.     int n;
  6.     struct linktype_s * next;  
  7. }LINKTYPE;

  8. int main()
  9. {
  10.     linktype_s* link = (linktype_s *) malloc(sizeof(linktype_s));

  11.     link->n = 1;
  12.     link->next = NULL;

  13.     long *p = (long*)((char*)(link) + sizeof(linktype_s) - sizeof(long*));

  14.     printf("address of p \'p\': %p\n", p);
  15.     printf("address of link->next: %p\n", &link->next);
  16.     printf("content of link->next: %p\n", link->next);

  17.     return 0;
  18. }
复制代码


程序运行的结果显示, 第一个和第二个输出结果是一样的,也就是说p的值实际上是next的地址,那么你的这段代码就有问题了:


  1. next=(char*)link+(nodesize-sizeof(long*));
  2.                 free(link);
  3.                 link=(void*)(*((long*)next));     
复制代码


首先next存放的是link中next的地址,free(link)之后这个地址失效,所以最后一句解引用可能就会出错,当然运气好的话不会segmentation fault.

我想正确的顺序应该是这样:

  1. next=(char*)link+(nodesize-sizeof(long*));
  2.                 void* p = (void*)(*((long*)next));     
  3.                 free(link);
  4.                 link= p;
复制代码


也就是说在free之前保存这个next指针的值.

论坛徽章:
0
48 [报告]
发表于 2007-08-16 23:36 |只看该作者
converse, 仔细看了你的回复,的确如你所说,有漏洞.多谢指正!
程序没有segmentation fault的原因估计是这样:
unix下,free()函数调用后系统并不立即收回也不清空被free的空间,所以程序本身也可以访问刚刚被free的地址;
其实下面这句改为取地址中的值就没有问题了,呵呵.
next=(char*)link+(nodesize-sizeof(long*));

TKS

论坛徽章:
0
49 [报告]
发表于 2007-08-16 23:40 |只看该作者
第一个free_nextbegin...()应该没有这个问题吧。
不过感觉
改成
next = *(void **)link;
看着自然些。
其实第二个
next=*(void **)((char*)link + nodesize-sizeof (long*));
就对了,就是说,第一次直接读出他包含的next的地址。

另外,我不是很清楚,如果这个结构体,在next指针不是结构体第一个成员时候。
如果使用pack指示符来编译,会不会有可能导致问题?

论坛徽章:
0
50 [报告]
发表于 2007-08-16 23:48 |只看该作者
另外,我不是很清楚,如果这个结构体,在next指针不是结构体第一个成员时候。
如果使用pack指示符来编译,会不会有可能导致问题


sizeof的值是跟随pack编译选项变动的,所以应该不会有问题.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP