回 帖 发 新 帖 刷新版面

主题:[讨论]用C写的串的链式存储表示,请帮我看一下错以哪里

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<stdlib.h>
#define NULL 0
#define CHUNKSIZE 10
#define LEN sizeof(struct chun)
typedef struct chun
{
    char *ch;
    struct chun *next;
}chunk;
struct list
{
    chunk *head,*tail;
    int curlen;
}lstring;
int strlength(char *s)
{   //返回串s的长度
    int i=0;
    while(s[i++])
        ;
    return i-1;
}
chunk *strcreat(char *s)
{   //对串s进行链式存储,每个结点默认为CHUNKSIZE,每个结点最后一个字符位存放'\0'
    chunk *p1,*p2;
    int cur=0,i;
    lstring.curlen=0;
    p1=p2=(chunk*)malloc(sizeof(LEN));  //开辟结点
    p1->ch=(char*)malloc(sizeof(char)*CHUNKSIZE);//开辟结点中存放串的空间
    lstring.head=NULL;
    for(i=0;i<strlength(s);i++,cur++)
    {
        if(cur==CHUNKSIZE-1)
        {

            if(lstring.head==NULL)
                lstring.head=p1;
            p1->ch[cur]='\0';
//            printf("%s",p1->ch);
            cur=0;
            p2->next=p1;
            p2=p1;
            p1=(chunk*)malloc(sizeof(LEN));
            p1->ch=(char*)malloc(sizeof(char)*CHUNKSIZE);
        }
        p1->ch[cur]=s[i];
        lstring.curlen++;
    }
    p1->ch[cur]='\0';  //最后一个结点的最后一个字符位存放'\0';
//    printf("%s\n",p1->ch);
    p1->next=NULL;
    return lstring.head;
}
void print(chunk *head)
{   //打印链表
    chunk *p;
    p=head;
    for(p=head;p!=NULL;p=p->next)
        printf("%s,",p->ch);
    printf("\n");
}
void main()
{
    chunk *head;
    char *s="abcdefghijklmnopqrstuvwxykwlqjfeioqpiurioewqjfklnwqioputz";
//    printf("%s\n",s);
    head=strcreat(s); //引用函数,对串s进行链式存储。
    print(head);
}

运行输出时,老是提示出错,请帮我检验一下

回复列表 (共9个回复)

沙发

改为:
 if(cur==CHUNKSIZE-1)
        {

            if(lstring.head==NULL)
                lstring.head=p1;
            p1->ch[cur]='\0';
            cur=0;
            p2=p1;
            p1=(chunk*)malloc(sizeof(LEN));
            p1->ch=(char*)malloc(sizeof(char)*CHUNKSIZE);
            p2->next=p1;

        }

板凳

不错啊,
能不能解释一下这是为什么
以前学链表的时候老师好像是用那样写的。
可现在怎么不行了,

3 楼

p1要先把自己的地址赋给p2,,然后在给p1分配新的存储空间,并让p2->next指向这个新的p1;

4 楼

p1=p2=(chunk*)malloc(sizeof(LEN));  //开辟结点
......
......
p2->next=p1;
p2=p1;
p1=(chunk*)malloc(sizeof(LEN)); 

.......
把p2的尾针指向p1,并将p2指向新结点p1,接着再开辟新结点p1,

这样好像也可解释得通,

5 楼

相比之下,你的写法不仅正确,而且更清晰

只是我不明白,以前正常的链表初始化方法现在用在串操作就不正常了

6 楼

#include<stdio.h>
#include<malloc.h>
#define NULL 0
#define LEN sizeof(struct list)
struct list
{
    int num;
    struct list *next;
};
struct list *creat(void)
{
    struct list *p1,*p2,*head=NULL;
    p1=p2=(struct list*)malloc(LEN);
    scanf("%d",&p1->num);
    while(p1->num)      //输入0表示结束
    {
        if(head==NULL)
            head=p1;
        p2->next=p1;         //跟一楼一样的写法,但运行起来一点问题都没有
        p2=p1;               //有点想不通。
        p1=(struct list*)malloc(LEN);
        scanf("%d",&p1->num);
    }
    p2->next=NULL;
    return head;
}
void print(struct list *head)
{
    struct list *p;
    for(p=head;p!=NULL;p=p->next)
        printf("%d,",p->num);
}
main()
{
    struct list *head;
    head=creat();
    print(head);
}

7 楼


p2->next=p1;
p2=p1;
p1=(chunk*)malloc(sizeof(LEN)); 

当你如此操作的以后,你也许会以为p2->next的地址和p1的一样了,其实不然,p2->next和p2还是指向同一个值,即:p2==p2->next,而p1指向另一个新空间,可以说此时p1和p2没有联系.当循环再次执行的时候,因为有p2->next=p1,此时他们才会连接上.执行p2=p1后,p2->next变为野指针;依次类推:
当你执行最后一个数组的时候p1和链表并没有任何联系,而此时的p2->next是一个野指针;所以你的最后一个结构体并没有连上.
当你输出最后一个的时候,就会报内存不能为读的错误.
而楼上和你的程序的区别就是他并没有用最后一个.所以不会报错.


8 楼

哈,,谢谢了,
茅塞顿开

9 楼

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CHUNKSIZE 10
#define LEN sizeof(struct chun)
typedef struct chun
{
    char *ch;
    struct chun *next;
}chunk;

typedef struct list
{
    chunk *head;
    int curlen;
}lstring;

int strlength(char *s)
{   //返回串s的长度
    int i=0;
    while(s[i++]) ;
    return i-1;
}
chunk *strcreat(char *s)
{   //对串s进行链式存储,每个结点默认为CHUNKSIZE,每个结点最后一个字符位存放'\0'
    lstring *p; chunk *p1,*p2;   int cur=0,i;   
    p=(struct list *)malloc(sizeof(struct list));
    p->head=(chunk *)malloc(LEN);   //头结点 
    p->curlen=0;
    p2=p->head;  //p2总指向表尾结点 
    p1=(chunk *)malloc(LEN);  //p1总指向新生的结点 
    p1->ch=(char*)malloc(sizeof(char)*CHUNKSIZE);
    for(i=0;i<strlength(s);i++,cur++)   
    {
        if(cur==CHUNKSIZE-1)  //如果到了串尾,赋予'\0'且生成新的结点
        {
            p1->ch[cur]='\0';
            cur=0;
            p2->next=p1;    //p1链接到表尾
            p2=p1;          //p2移动下一个结点
            p1=(chunk *)malloc(LEN);
            p1->ch=(char *)malloc(sizeof(char)*CHUNKSIZE);
        }      
        p1->ch[cur]=s[i];    
        p->curlen++;    
    }
    p1->ch[cur]='\0';   //最后一个结点的最后一个字符位存放'\0';
    p2->next=p1;       //------注意:最后一个结点要链入表尾----------
    p2=p1;   
    p2->next=NULL;    
    p1=NULL;
    return p->head;
}

void print(chunk *head)
{   //打印链表
    chunk *p;
    for(p=head->next;p!=NULL;p=p->next)
        printf("%s\n",p->ch);
    printf("\n");
}
main()
{
    chunk *head;
    char *s="abcdefghijklmnopqrstuvwxykwlqjfeioqpiurioewqjfklnwqioputz";
    printf("%d\n",strlength(s));
    head=strcreat(s); //引用函数,对串s进行链式存储。
    print(head);
    system("pause");
}






我来回复

您尚未登录,请登录后再回复。点此登录或注册