| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1057 人关注过本帖
标题:请教:我想做一个比较特别的双向列表,指针作加法有点问题,大家帮我看看!
取消只看楼主 加入收藏
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:11 
请教:我想做一个比较特别的双向列表,指针作加法有点问题,大家帮我看看!
我写了个结构体如下:
struct shm_data_st{
    struct shm_data_st *pre;
    char data[10];
    struct shm_data_st *next;
};
然后用共享内存的方法得到了一快空白区域,我现在让shm_head,shm_tail指向队列起始位置,从这开始让几个结构体紧密排列
一个挨着一个,让前一个结构题的next指针指向自己后面的第一个字节,
    for(num=0;num<NUM;num++){
        shm_head->next = shm_head + sizeof(struct shm_data_st);//指向下一个元素  ==》发现这步不能将指针指向自己后面的第一个字节
        shm_tail = shm_head->next;                             //移动尾指针
        shm_tail->pre = shm_head;                              //尾指针指向前一个元素
        shm_head = shm_tail;                                   //将头指针移到尾指针
    }
    n_data->pre = shm_tail;                              //初始化第一个元素的pre
    shm_tail->next = n_data;
请大家帮我看看是什么原因导致的,是不是指针不能这样相加啊!!

[[it] 本帖最后由 asmdaydream 于 2009-7-25 16:01 编辑 [/it]]
搜索更多相关主题的帖子: 列表 指针 加法 
2009-07-25 15:56
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
谢谢,好像转换成char* 可以通过编译,
不过,执行后好像地址没有加上去
    for(num=0;num<NUM;num++){
        printf("ox%x:shm_head->next\n",&shm_head);
        printf("Add size :%d \n", sizeof(struct shm_data_st));
        shm_head->next = (char*)shm_head + sizeof(struct shm_data_st);//指向下一个元素
        printf("ox%x:shm_head->next\n\n",&shm_head);
        shm_tail = shm_head->next;                             //移动尾指针
        shm_tail->pre = shm_head;                              //尾指针指向前一个元素
        shm_head = shm_tail;                                   //将头指针移到尾指针
    }

ox804b088:shm_head->next
Add size :116
ox804b088:shm_head->next

ox804b088:shm_head->next
Add size :116
ox804b088:shm_head->next

ox804b088:shm_head->next
Add size :116
ox804b088:shm_head->next

ox804b088:shm_head->next
Add size :116
ox804b088:shm_head->next

ox804b088:shm_head->next
Add size :116
ox804b088:shm_head->next

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-25 16:20
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
不好意思,输出函数写得太粗心了
地址好像加上去了,只是地址有点奇怪,head没有走
ox804b088:shm_head
Add size :116
oxb8091070:shm_head->next

ox804b088:shm_head
Add size :116
oxb80910e4:shm_head->next

ox804b088:shm_head
Add size :116
oxb8091158:shm_head->next

ox804b088:shm_head
Add size :116
oxb80911cc:shm_head->next

ox804b088:shm_head
Add size :116
oxb8091240:shm_head->next
可能是程序有问题把,指针没有前进

[[it] 本帖最后由 asmdaydream 于 2009-7-25 16:44 编辑 [/it]]

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-25 16:30
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
谢谢,
这样执行后是不是在for循环里面给指针赋值的时候会发生覆盖现象?++pt移动了一个字节,指针会占用4个字节的大小
还有pt[-1].next=NULL 我确实不明白这句话的作用也不知道是怎么来的

还有为什么返回memory,memory没有改变,是否应该将最后的pt返回?

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-25 19:03
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
谢谢,我先看看

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-25 22:19
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
不好意思,我的是linux环境,稍微修改了一下程序才能运行
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


struct shm_data_st
{
    struct shm_data_st *pre;
    char data[10];
    struct shm_data_st *next;
};

struct shm_data_st *init_shm_data(struct shm_data_st *memory,size_t size)   //把参数类型改了一下
{
    struct  shm_data_st *pt = memory;
    struct  shm_data_st *end = memory + size;

    assert(memory != NULL && size != 0);

    for (; pt < end; ++pt)
    {
        pt->pre = pt - 1;
#ifndef NDEBUG
        sprintf(pt->data, "struct %d", pt - (struct shm_data_st*)memory);
#endif /* NDEBUG */
        pt->next = pt + 1;
    }

    ((struct shm_data_st*)memory)->pre = NULL;
    pt[-1].next = NULL;

    return memory;
}

int main(void)
{
    char buf[1000];
    struct shm_data_st *pt;
    pt = (struct shm_data_st*)malloc(sizeof(struct shm_data_st));
    struct shm_data_st *temp = (struct shm_data_st *)buf;
    init_shm_data(pt, 1000);     //这个实参换了一个,不然通不过断言
    init_shm_data(temp, 1000);

    for (pt = (struct shm_data_st*)buf; pt != NULL;pt = pt->next)
    {
        puts(pt->data);
    }
    return 0;
}
/* cc: flags+='-DNDEBUG' */
程序在for循环里面出现了问题,有时候是pt->pre访问了不能访问的内存地址,有时候是pt->next,不过是循环多次以后才出现的,是否需要申请一块比较的的空间,当指针指向结构体后面以后的地址时,地址否可用我们并不能确定 所以才会有时候就是pt->pre,有时候就是 ptr->next访问了不能访问的内存空间
而且还发现,虽然for循环里面 ++pt 但是通过 printf 输出的结果来看,好现pt的地址没有变过,
我是用 printf("0x:%x", &pt);输出的,不知道有没有问题

先前我的pt+1的理解是错误的,pt+1实际上应该是pt + 1*(sizeof(struct shm_data_st))
还有pt[-1].next,这个真是不认识,在网上找了一下,好像不能搜索[],以前也没有见过
其实昨天的时候我是测试的一个比较简单的程序,是能够,使用shm_head->next = shm_head + sizeof(struct shm_data_st)的
但是今天重新写了一遍,就发现这句话达不到目的了很奇怪。这个我都是在一大片共享内存里面测试的。

[[it] 本帖最后由 asmdaydream 于 2009-7-26 03:39 编辑 [/it]]

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-26 02:43
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
恩,在终端下用gcc可以编译,结果也一样,之前我是用的  NetBeans IDE环境  版本比较高可能对语法要求严格,

那句pt[-1].next = NULL到底是什么啊,我在网上也没有找到相关的资料,没有见过 难道 [-1]. 就是等于 -> ,或是 pt-1 别的什么?

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-26 07:48
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
谢谢 StarWing83 终于弄明白了
程序开始申请了1000字节的空间 buf[1000]
init_shm_data(memory, size)第一个参数是空间的起始地址,size是空间的大小
这个函数里面定义的两个指针用来保证不会访问到 1000 以外的地址
++PT 就已经实现了 pt指向结构体后面的一个字节,就像一个数组一样
    后面两句在初始化,第一个数组的pre 最后一个数组的next
    pt[-1].next = NULL; 这个虽然我没有找到,根据意思就是,pt-1了,
在最后一次移动的时候超过了1000 pt-1,移回最后一个位置。

很巧妙的思想,比起我想的方便多了,不容易错,别人还容易看懂,厉害

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-26 08:18
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
思想是最重要的,
这个问题让我学到很多,谢谢了StarWing83!

[[it] 本帖最后由 asmdaydream 于 2009-7-26 09:07 编辑 [/it]]

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-26 08:58
asmdaydream
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:中原
等 级:版主
威 望:13
帖 子:257
专家分:840
注 册:2009-5-10
收藏
得分:0 
呵呵,创建的时候是 .c 后缀的,不能编译主要是因为指针类型不同导致的错误,修改一下就好了,最后执行的时候应该就是最后一次访问出现的段错误,因为我通过控制结构体的个数后段错误就没有发生了

常走夜路不怕黑 长沙PHP高薪招聘群6K+ 95926136
2009-07-26 20:10
快速回复:请教:我想做一个比较特别的双向列表,指针作加法有点问题,大家帮我看 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018601 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved