请教 指针地址为什么会变

donglq 2009-08-19 09:25:28
我需要一个动态链表来存储服务器发来的数据,过程是这样的,服务器发来的数据先放在一个临时变量tmpVdata里面,然后创建一个节点,再调用insertNode把节点插到链表尾部,但是奇怪的是我在insert函数里面把打印出来的节点地址和外面的不一样,相关代码如下:
void insertItem(BufferListItem const head, BufferListItem insertNode)
{
BufferListItem pVdata = head;
while(pVdata->videoDataLink!=NULL){
pVdata = pVdata->videoDataLink;
}
pVdata->videoDataLink = insertNode;
printf("pVdata addr in insertItrm : %x\n",pVdata);//此处地址为442098
insertNode->videoDataLink = NULL;
}

……
insertItem(tmpHead, tmpVdata);//对insert的调用位于一个线程里面
printf("head link addr after insert:%x\n",tmpHead->videoDataLink);//此处地主为27600000
...全文
367 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
野男孩 2009-10-04
  • 打赏
  • 举报
回复
这能一样吗?!!

pVdata->videoDataLink = insertNode;
printf("pVdata addr in insertItrm : %x\n",pVdata);//此处地址为442098
函数里面这个pVdata是头节点tmpHead的地址

而调用的地方,下面这个printf打印的是tmpHead->VedioDataLink的值

insertItem(tmpHead, tmpVdata);//对insert的调用位于一个线程里面
printf("head link addr after insert:%x\n",tmpHead->videoDataLink);//此处地主为27600000


都不是一个东西,打印出来能一样就怪了。
shashenyidaoOCEAN 2009-10-04
  • 打赏
  • 举报
回复
学习来了!
macrojj 2009-10-04
  • 打赏
  • 举报
回复
printf("pVdata addr in insertItrm : %x\n",pVdata->videoDataLink);


正解。
你之前打印的是pVdata在栈中的地址。这样才是结点的地址
  • 打赏
  • 举报
回复

值传递当然不一样,如果传引用或指针试一试
wanghao111 2009-10-03
  • 打赏
  • 举报
回复
我重新拿起了课本啊
wanghao111 2009-10-03
  • 打赏
  • 举报
回复
重新学习
donglq 2009-10-03
  • 打赏
  • 举报
回复
最近在看C++ primer, C++ 里面确实不支持typedef struct BufferListItem *BufferListItem 这样的定义,至于地址为什么会变 个人觉得是形参和引用之间的差异造成的,这个应该对新手来说是个比较难以理解的问题,期待高手的解释
xue040506 2009-08-20
  • 打赏
  • 举报
回复
可能是用的编译器不同吧,本来C语言的编译器就不是很严格,而且还带欺骗性,可以随意的强制类型转换,我是在C++的编译器下做的,在typedef struct BufferListItem *BufferListItem;这一行报下面错误:
error C2040: “BufferListItem”: “BufferListItem *”与“BufferListItem”的间接寻址级别不同。我去LINUX试了下,你的定义也可以通过。而且打出来的地址也是一样的,不知道你的代码是什么样的,个人觉得没理由不一样,无能为力了,等高手帮你吧,记得解决的时候把问题帖出来啊,呵呵。
donglq 2009-08-20
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 xue040506 的回复:]
对呀,这不就对了,你的意图和我上面分析的结果完全吻合,insertItem逻辑上对着了,只是你打印语句错了,我楼上的兄弟也发现了,改成他那样应该打出来就一样了,你里面打印的都不是一个东西。

楼主本来我一直没想运行你代码,这么个问题想也想得明白,上面的结果都是看出来的,为了100%的正确,所以试了一下,都没注意你结构体是这样定义的,晕死我了,我改了你的结构体定义,完全可以打印出来,两个结果一样,所以是正确的。只是你看看下面

这是你拷贝出来的??,有大问题啊,怎么可以这样定义?
typedef struct BufferListItem *BufferListItem; //这句也不对,定义成指针时名字不能一样。
typedef struct BufferListItem BufListItem;

struct BufferListItem {
unsigned short PackSize;
unsigned char *videoData;
BufferListItem videoDataLink;  //这一句就错的够厉害了,BufferListItem *videoDataLink;
};


[/Quote]

谢谢你的回答,不过我的定义是没有错误的
typedef struct BufferListItem *BufferListItem;
上面这句这样定义是很正确的做法,这句话的意思是 struct BufferListItem = *BufferListItem
你可以琢磨下,这个是没有错误的,至于你说的下面那个错的厉害的,只有你理解了上面这句定义的意思才会领会到;不过还是非常感谢你的回答。
也多谢各位回帖的朋友!
我想申明一点,各位不要再从这个定义看问题,这个是完全没有错的,难道各位没注意到两次打印出的地址长度就是不一样的
xiaodage 2009-08-19
  • 打赏
  • 举报
回复
lg
Paradin 2009-08-19
  • 打赏
  • 举报
回复
pVdata->videoDataLink = insertNode;
printf("pVdata addr in insertItrm : %x\n",pVdata->videoDataLink);
donglq 2009-08-19
  • 打赏
  • 举报
回复
上面有个地方写错了 是insertNode->link = NULL
donglq 2009-08-19
  • 打赏
  • 举报
回复
我完整的说一次吧 开始先创建头节点head,头结点的data为空,link也为空,第二个节点insertNode就开始调用insert,相当于插到head后面,也就是说head->link = insertNode,insertNode= NULL;我的问题是我在insert函数里面打印出的地址head->link和insert外面打印出的地址head->link 不一样
xue040506 2009-08-19
  • 打赏
  • 举报
回复
根据你贴出的代码看来:传入的tmpHead肯定不能为空,而且你说空间都已经分配好,tmpVdata就是分配好的新地址,那你在调用insertItem时链表已经是至少有一个节点了,调用insertItem只能插入第二个,第三个。。。,因为它不能操作第一个节点,只能修改第一个节点的内容,而不能改变它指向的地址,因为你定义的时候用了const,这样看来,这段代码是正确的,打印是你的问题,如果真是我说的这样,insertItem逻辑上对着了,你看看你的意图是这样的吗?看不出什么了,希望能帮到你。或者说说你的现在的问题
donglq 2009-08-19
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 xue040506 的回复:]
楼主不知道你发现了没有,你的代码有BUG,不知道你是怎么用,如果开始链表为空,第一次插入时你传入的tmpHead是什么值,如果空值,BUG就发生了,NULL->videoDataLink!=NULL,是意想不到的值,可能是我没理解你的意思,你自己再想想。
还有如果是动态链表,最好是在生成链表的函数内部分配动态内存空间,从你的代码中看不出有这操作,是否在外部为每个将要插入的节点分配好了,貌似没有,因为你的tmpVdata是临时的,这样看来你的数据根本没有保存起来。
至于你打两次打印结果不同估计你已经明白了,自己再检查一下代码,指针不可怕,可怕的是不底清,好好分析代码和数据存储的结构。
[/Quote]

我只是贴出一部分代码,相关的操作,创建节点,申请空间都有的 你说的我已经明白了是什么意思
xue040506 2009-08-19
  • 打赏
  • 举报
回复
楼主不知道你发现了没有,你的代码有BUG,不知道你是怎么用,如果开始链表为空,第一次插入时你传入的tmpHead是什么值,如果空值,BUG就发生了,NULL->videoDataLink!=NULL,是意想不到的值,可能是我没理解你的意思,你自己再想想。
还有如果是动态链表,最好是在生成链表的函数内部分配动态内存空间,从你的代码中看不出有这操作,是否在外部为每个将要插入的节点分配好了,貌似没有,因为你的tmpVdata是临时的,这样看来你的数据根本没有保存起来。
至于你打两次打印结果不同估计你已经明白了,自己再检查一下代码,指针不可怕,可怕的是不底清,好好分析代码和数据存储的结构。
Paradin 2009-08-19
  • 打赏
  • 举报
回复
如果是第一次插入的话
printf("pVdata addr in insertItrm : %x\n",pVdata);//此处地址为442098
此处的pVdata 应该就是head吧
pVdata->videoDataLink 和 tmpHead->videoDataLink才是一样的吧?
Paradin 2009-08-19
  • 打赏
  • 举报
回复
类型名有点混乱。。
帮顶了
donglq 2009-08-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lpr_pro 的回复:]
void insertItem(BufferListItem const head, BufferListItem insertNode)
这个函数第二个参数inertNode使用指针,或引用类型,否则只是形参变量,在函数体内和函数外的地址是不一样的.
[/Quote]
我的问题就是为什么会不一样,要是不一样我插入的节点不是找不到了么
donglq 2009-08-19
  • 打赏
  • 举报
回复
谢谢各位的回贴,针对1楼指出的问题,我已回答过,见7楼,个人觉得2楼说的有道理,请各位再帮帮忙,这个问题已经困扰小弟好几天了
加载更多回复(11)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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