链表中的数据被破坏

问题描述 投票:0回答:1

我用结构体制作了链表。 第一个字符串运行良好,但第二个字符串不是“am”,而是出现随机字符。 第三个及之后的一个,指针被破坏,并且出现异常,“分段错误”。 这是代码。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct strliststruct{
    char* string;
    unsigned long long length;
    struct strliststruct* prior;
    struct strliststruct* later;
    int exist_prior;
    int exist_later;
}strlist;

strlist init_strlist(){
    strlist ans;
    ans.exist_later=0;
    ans.exist_prior=0;
    ans.length=0;
    return ans;
}

strlist init_strlist_with_string(char* str,char splitter){
    strlist ans=init_strlist(),next;
    unsigned long long i;
    for(i=0;1;i++){
        if(str[i]==splitter){
            next=init_strlist_with_string(&str[i+1],splitter);
            ans.later=&next;
            ans.exist_later=1;
            next.exist_prior=1;
            next.prior=&ans;
        }else if(str[i]!='\0'){continue;}
        ans.string=malloc(sizeof(char)*(i+1));
        ans.string[i]='\0';
        for(unsigned long long j=0;j<i;j++){
            ans.string[j]=str[j];
        }
        break;
    }
    return ans;
}
int main(){
    strlist sl=init_strlist_with_string("I am a human",' ');
    while(1){
        printf("%s\n",sl.string);
        if(sl.exist_later){sl=*sl.later;}else break;
    }
    return 0;
}

我使用 Visual Studio 代码,并使用 gcc 对其进行编译。

我试图找出为什么会导致断点,发现第四个指针在第四个“ans.string=malloc”上被删除。 第二个及以后的数据在“sl=sl.later”上被销毁。 我不知道解决方案。

c pointers struct
1个回答
0
投票

我必须避免将局部变量作为指针返回,这会在函数结束后销毁。所以, 相反,使用 malloc 来保留内存将是解决方案。这是改进后的代码。

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct strliststruct{
    char* string;
    unsigned long long length;
    struct strliststruct* prior;
    struct strliststruct* later;
    int exist_prior;
    int exist_later;
}strlist;

strlist* init_strlist(){
    strlist *ans=malloc(sizeof(strlist));
    ans->exist_later=0;
    ans->exist_prior=0;
    ans->length=0;
    return ans;
}

strlist* init_strlist_with_string(char* str,char splitter){
    strlist *ans=init_strlist(),*next;
    unsigned long long i;
    /*for(i=0;1;i++){
        if(str[i]==splitter){
            next=init_strlist_with_string(&str[i+1],splitter);
            ans->later=next;
            ans->exist_later=1;
            next->exist_prior=1;
            next->prior=ans;
        }else if(str[i]!='\0'){
            continue;
        }
        ans->length=j;
        ans->string=malloc(sizeof(char)*(i+1));
        ans->string[i]='\0';
        for(unsigned long long j=0;j<i;j++){
            ans->string[j]=str[j];
        }
        break;
    }*/

    unsigned long long nextspl=strchr(str,'\0')-str;
    if(strchr(str,splitter)){
        nextspl=strchr(str,splitter)-str;
        next=init_strlist_with_string(&str[nextspl+1],splitter);
        ans->later=next;
        ans->exist_later=1;
        next->exist_prior=1;
        next->prior=ans;
    }
    ans->length=nextspl;
    ans->string=malloc(sizeof(char)*(nextspl+1));
    memcpy(ans->string,str,nextspl);
    ans->string[nextspl]='\0';

    return ans;
}
int main(){
    strlist *sl=init_strlist_with_string("I am a human",' ');
    while(1){
        printf("%s\n",sl->string);
        if(sl->exist_later){
            sl=sl->later;
        }else{
            break;
        }
    }
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.