免费注册 查看新帖 |

Chinaunix

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

[C]void指针赋值后,地址值发生了变化 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2011-09-28 09:44 |只看该作者
回复 9# nbaloverme


    那就费解了。我再想想
    顺便说一下
   fprintf(stderr, "queue address: %p\n",my queue);
   多写了一个空格,不过这个和你的那个问题似乎应该没什么关系

论坛徽章:
0
12 [报告]
发表于 2011-09-28 09:45 |只看该作者
myqueue是static

论坛徽章:
0
13 [报告]
发表于 2011-09-28 10:06 |只看该作者
回复 11# KBTiller


    写这个帖子时编辑错误,多打了个空格。

论坛徽章:
0
14 [报告]
发表于 2011-09-28 10:07 |只看该作者
回复 12# deadlylight


    和这个没有关系,改成非static变量也一样。

论坛徽章:
0
15 [报告]
发表于 2011-09-28 10:30 |只看该作者
回复  KBTiller


    写这个帖子时编辑错误,多打了个空格。
nbaloverme 发表于 2011-09-28 10:06




这就说明帖子里的code和实际的不是完全相同,不是你直接复制下来的
问题往往就在你没注意到的细节

论坛徽章:
0
16 [报告]
发表于 2011-09-28 10:43 |只看该作者
贴二段运行时的输出吧,第一个是正常运行,第二个是运行时出现段错误。
queue address: (nil)
queue address is 0x12a8710
queue address: 0x12a8710

queue address: (nil)
queue address is 0x2aaaac008680
queue address: 0xffffffffac008680


在较高地址时经过赋值后地址值就变了,高位全部置为F。
每次运行结果都这样。

论坛徽章:
0
17 [报告]
发表于 2011-09-28 12:34 |只看该作者
本帖最后由 雨过白鹭洲 于 2011-09-28 12:36 编辑

回复 3# nbaloverme


Sorry, 是我没看仔细。。

  1. void* queue_new(uint32_t size) {
  2.         queue *q = NULL;
  3.         q = (queue*)malloc(sizeof(queue));
  4.         passert(q);
  5.         q->head = NULL;
  6.         q->tail = &(q->head);
  7.         q->elements = 0;
  8.         q->size = 0;
  9.         q->maxsize = size;
  10.         q->freewaiting = 0;
  11.         q->fullwaiting = 0;
  12.         if (size) {
  13.                 eassert(pthread_cond_init(&(q->waitfull),NULL)==0);
  14.         }
  15.         eassert(pthread_cond_init(&(q->waitfree),NULL)==0);
  16.         eassert(pthread_mutex_init(&(q->lock),NULL)==0);
  17.         fprintf(stderr,"queue address is %p\n",q);
  18.         return (void*)q;
  19. }

  20. static void *myqueue;
  21. fprintf(stderr, "queue address: %p\n",my queue);
  22. myqueue = (void *)queue_new(0);   // 我怀疑这里没找到queue_new()函数的原型声明,编译器将函数的返回值默认为int;
  23.                               // 此时已经发生了截断,从64位指针截断为32位的int。然后你再将int强制转换为(void*),于是高32位全部置为FF
  24. fprintf(stderr, "queue address: %p\n", myqueue);
复制代码
楼主你试下是不是这个原因

另外太多的强制转换,不是好的编程习惯,因为这样会把许多编译器警告屏蔽,导致非常微妙的错误。

论坛徽章:
0
18 [报告]
发表于 2011-09-28 13:22 |只看该作者
+1
回复 17# 雨过白鹭洲

论坛徽章:
0
19 [报告]
发表于 2011-09-28 13:32 |只看该作者
感觉象是内存分页引起的,linux下的LWP线程在内核中分配一个TASK,每个TASK中堆栈的起始地址不同,这样可能造成楼主那种情况发生吧? 最好显示下程序中堆栈内存分布。

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27白羊座
日期:2014-08-07 12:36:42丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
20 [报告]
发表于 2011-09-28 13:44 |只看该作者
17楼是对的,仔细看看LZ运行正确的情况和出现段错误的情况:

0x12a8710 时转换为int型后在转换为void*可以保持不变,因为0x12a8710作为int型值是个正数,所以转换为void*这种无符号数时高位是全填的0。

0x2aaaac008680进行截断后作为int型值就是个负数了(0xac008680最高位为1),转换为void*就高位全填1了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP