C 从函数返回链表时出现分段错误

C 从函数返回链表时出现分段错误,c,linked-list,segmentation-fault,C,Linked List,Segmentation Fault,我有下面的代码,它打印文件夹中有结尾的文件。 默认情况下,它还会显示以“SCL_10m.tif”结尾的文件。 这是迄今为止行之有效的版本: #include <dirent.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include "gdal/gdal.h" #include "gdal/cpl_conv.h" #include <stdio.h> #i

我有下面的代码,它打印文件夹中有结尾的文件。 默认情况下,它还会显示以“SCL_10m.tif”结尾的文件。 这是迄今为止行之有效的版本:

#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "gdal/gdal.h"
#include "gdal/cpl_conv.h"
#include <stdio.h>
#include <time.h>


// Linked-List
typedef struct nlist{
    char *data;
    struct nlist *next;
}Node;

// Function to replace a string with another 
// string 
char* str_replace(char* string, const char* substr, const char* replacement) {
    char* tok = NULL;
    char* newstr = NULL;
    char* oldstr = NULL;
    int   oldstr_len = 0;
    int   substr_len = 0;
    int   replacement_len = 0;

    newstr = strdup(string);
    substr_len = strlen(substr);
    replacement_len = strlen(replacement);

    if (substr == NULL || replacement == NULL) {
        return newstr;
    }

    while ((tok = strstr(newstr, substr))) {
        oldstr = newstr;
        oldstr_len = strlen(oldstr);
        newstr = (char*)malloc(sizeof(char) * (oldstr_len - substr_len + replacement_len + 1));

        if (newstr == NULL) {
            free(oldstr);
            return NULL;
        }

        memcpy(newstr, oldstr, tok - oldstr);
        memcpy(newstr + (tok - oldstr), replacement, replacement_len);
        memcpy(newstr + (tok - oldstr) + replacement_len, tok + substr_len, oldstr_len - substr_len - (tok - oldstr));
        memset(newstr + oldstr_len - substr_len + replacement_len, 0, 1);

        free(oldstr);
    }

    free(string);

    return newstr;
}


Node* insert(Node*, char*);
void show(Node*);

//Function to insert an element in the linked-list
Node* insert(Node *Head, char *value)
{
    Node *new_string;
    new_string = (Node *)malloc(sizeof(Node));
    new_string->data = malloc(strlen(value)+1);
    strcpy(new_string->data,value);
    Node *check;
    check = (Node *)malloc(sizeof(Node));

    if(Head == NULL){
        Head = new_string;
        Head->next = NULL;
    }
    else{
        check = Head;
        while(check->next != NULL)
            check = check->next;

        check->next = new_string;
        new_string->next = NULL;
    }
    return Head;
}

//Function to show the elements in the linked-list
void show(Node *Head)
{
    Node *check;
    check = (Node *)malloc(sizeof(Node));
    check = Head;
    if (check == NULL){
        return;
    }

    while(check != NULL) {
        printf("%s", check->data);
        check=check->next;
    }
    printf("\n");
}

//Function to find the files in the folder recursively based on 
// a wildcard, and adding them to a linked-list
void listFilesRecursively(char *path, char *suffix);

//checks if a string ends with a substring
int string_ends_with(const char * str, const char * suffix)
{
    int str_len = strlen(str);
    int suffix_len = strlen(suffix);

    return 
        (str_len >= suffix_len) &&
        (0 == strcmp(str + (str_len-suffix_len), suffix));
}

void listFilesRecursively(char *basePath, char *suffix)
{
    char path[1000];
    struct dirent *dp;
    DIR *dir = opendir(basePath);
    Node *Head = NULL;

    if (!dir)
        return;

    while ((dp = readdir(dir)) != NULL)
    {
        if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
        {
            strcpy(path, basePath);
            strcat(path, "/");
            strcat(path, dp->d_name);

            if (string_ends_with(path, suffix))
                Head = insert(Head, path);
            listFilesRecursively(path, suffix);
        }
    }

    show(Head);
    closedir(dir);
}

int main()
{
    char path[100];
    char suffix[100];

    // Input path from user
    // Suffix Band Sentinel-2 of Type B02_10m.tif

    printf("Enter path to list files: ");
    scanf("%s", path);
    printf("Enter the wildcard: ");
    scanf("%s", suffix);
    char *SCL_suffix = "SCL_10m.tif";
    listFilesRecursively(path, suffix);
    listFilesRecursively(path, SCL_suffix);

    return 0;
}
#包括
#包括
#包括
#包括
#包括“gdal/gdal.h”
#包括“gdal/cpl_conv.h”
#包括
#包括
//链表
类型定义结构列表{
字符*数据;
结构nlist*next;
}节点;
//函数将字符串替换为另一个字符串
//串
char*str_替换(char*string,const char*substr,const char*replacement){
char*tok=NULL;
char*newstr=NULL;
char*oldstr=NULL;
int oldstr_len=0;
int substr_len=0;
整数替换_len=0;
newstr=strdup(字符串);
substr_len=strlen(substr);
更换=斯特伦(更换);
if(substr==NULL | | replacement==NULL){
返回新闻TR;
}
而((tok=strstrstr(newstr,substr))){
oldstr=newstr;
oldstr_len=strlen(oldstr);
newstr=(char*)malloc(sizeof(char)*(oldstr_len-substr_len+replacement_len+1));
if(newstr==NULL){
免费(oldstr);
返回NULL;
}
memcpy(newstr、oldstr、tok-oldstr);
memcpy(newstr+(tok-oldstr),替换,替换;
memcpy(newstr+(tok-oldstr)+替换项,tok+子项,oldstr-子项-(tok-oldstr));
memset(newstr+oldstr-substr-len+replacement-len,0,1);
免费(oldstr);
}
自由(弦);
返回新闻TR;
}
节点*插入(节点*,字符*);
虚空显示(节点*);
//函数在链表中插入元素
节点*插入(节点*头,字符*值)
{
节点*新的_字符串;
new_string=(Node*)malloc(sizeof(Node));
新建字符串->数据=malloc(strlen(值)+1);
strcpy(新字符串->数据、值);
节点*检查;
检查=(节点*)malloc(sizeof(节点));
if(Head==NULL){
头=新的_字符串;
Head->next=NULL;
}
否则{
检查=头部;
while(检查->下一步!=NULL)
检查=检查->下一步;
检查->下一步=新字符串;
新建字符串->下一步=空;
}
回流头;
}
//函数以显示链接列表中的元素
无效显示(节点*头部)
{
节点*检查;
检查=(节点*)malloc(sizeof(节点));
检查=头部;
如果(检查==NULL){
返回;
}
while(检查!=NULL){
printf(“%s”,检查->数据);
检查=检查->下一步;
}
printf(“\n”);
}
//函数以基于递归方式查找文件夹中的文件
//一个通配符,并将其添加到链接列表中
递归地作废列表文件(char*路径,char*后缀);
//检查字符串是否以子字符串结尾
int字符串以(常量字符*字符串,常量字符*后缀)结尾
{
int str_len=strlen(str);
int后缀_len=strlen(后缀);
返回
(str_len>=后缀_len)&&
(0==strcmp(str+(str_len-后缀_len),后缀));
}
递归作废列表文件(字符*基本路径,字符*后缀)
{
字符路径[1000];
结构方向*dp;
DIR*DIR=opendir(基本路径);
Node*Head=NULL;
如果(!dir)
返回;
而((dp=readdir(dir))!=NULL)
{
如果(strcmp(dp->d_name,“.”)=0和&strcmp(dp->d_name,“…”)!=0)
{
strcpy(路径、基本路径);
strcat(路径“/”;
strcat(路径,dp->d_名称);
if(字符串以(路径,后缀)结尾)
头部=插入(头部,路径);
递归地列出文件(路径、后缀);
}
}
秀(头);;
closedir(dir);
}
int main()
{
字符路径[100];
字符后缀[100];
//来自用户的输入路径
//B02_10m.tif型后缀带Sentinel-2
printf(“输入列表文件的路径:”);
scanf(“%s”,路径);
printf(“输入通配符:”);
scanf(“%s”,后缀);
char*SCL_suffix=“SCL_10m.tif”;
递归地列出文件(路径、后缀);
递归地列出文件(路径、SCL_后缀);
返回0;
}
我开始编写这段代码,做了一些修改,最重要的是,我没有通过调用show(Head)递归地打印函数listfiles中生成的链表,而是希望将列表返回到主函数以进行其他处理(同时迭代两个列表,这是未来的工作)

但是,在main()中执行此操作并递归调用函数listfiles两次后,我遇到了一个分段错误

根据某些来源,如果函数传递或返回指向堆栈上某个对象的指针,则会发生分段错误,堆栈是存储临时变量的内存区域。我一直在递归地检查listfiles函数,在其中处理指针,但我无法解决这个问题。如果您能在这个问题上提供一些帮助,我们将不胜感激

下面是导致分段错误的代码的修改版本

include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "gdal/gdal.h"
#include "gdal/cpl_conv.h"
#include <stdio.h>
#include <time.h>


// Node Structure of Linked-List
typedef struct nlist{
    char *data;
    struct nlist *next;
}Node;

// Function to replace a string with another 
// string 
char* str_replace(char* string, const char* substr, const char* replacement) {
    char* tok = NULL;
    char* newstr = NULL;
    char* oldstr = NULL;
    int   oldstr_len = 0;
    int   substr_len = 0;
    int   replacement_len = 0;

    newstr = strdup(string);
    substr_len = strlen(substr);
    replacement_len = strlen(replacement);

    if (substr == NULL || replacement == NULL) {
        return newstr;
    }

    while ((tok = strstr(newstr, substr))) {
        oldstr = newstr;
        oldstr_len = strlen(oldstr);
        newstr = (char*)malloc(sizeof(char) * (oldstr_len - substr_len + replacement_len + 1));

        if (newstr == NULL) {
            free(oldstr);
            return NULL;
        }

        memcpy(newstr, oldstr, tok - oldstr);
        memcpy(newstr + (tok - oldstr), replacement, replacement_len);
        memcpy(newstr + (tok - oldstr) + replacement_len, tok + substr_len, oldstr_len - substr_len - (tok - oldstr));
        memset(newstr + oldstr_len - substr_len + replacement_len, 0, 1);

        free(oldstr);
    }

    free(string);

    return newstr;
}


Node* insert(Node*, char*);
void show(Node*);

// Function to insert an element to the Linked-List
Node* insert(Node *Head, char *value)
{
    Node *new_string;
    new_string = (Node *)malloc(sizeof(Node));
    new_string->data = malloc(strlen(value)+1);
    strcpy(new_string->data,value);
    Node *check;
    check = (Node *)malloc(sizeof(Node));

    if(Head == NULL){
        Head = new_string;
        Head->next = NULL;
    }
    else{
        check = Head;
        while(check->next != NULL)
            check = check->next;

        check->next = new_string;
        new_string->next = NULL;
    }
    return Head;
}

//Function to show the elements of the Linked-List
void show(Node *Head)
{
    Node *check;
    check = (Node *)malloc(sizeof(Node));
    check = Head;
    if (check == NULL){
        return;
    }

    while(check != NULL) {
        printf("%s", check->data);
        check=check->next;
    }
    printf("\n");
}

//Function to check if a string finishes with a suffix
int string_ends_with(const char * str, const char * suffix)
{
    int str_len = strlen(str);
    int suffix_len = strlen(suffix);

    return 
        (str_len >= suffix_len) &&
        (0 == strcmp(str + (str_len-suffix_len), suffix));
}


Node *listFilesRecursively(char*, char*);

//Function to find the files in a directory based on a wildcard
Node *listFilesRecursively(char *basePath, char *suffix)
{
    char path[1000];
    struct dirent *dp;
    DIR *dir = opendir(basePath);
    Node *Head = NULL;
    Node *Head_scl = NULL;

    //if (!dir)
    //    return;

    while ((dp = readdir(dir)) != NULL)
    {
        if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
        {
            strcpy(path, basePath);
            strcat(path, "/");
            strcat(path, dp->d_name);

            if (string_ends_with(path, suffix))
                Head = insert(Head, path);
            listFilesRecursively(path, suffix);
        }
    } 
    //show(Head);
    closedir(dir);
    return Head;
}


int main()
{
    char path[100];
    char suffix[100];

    // Input path from user
    // Suffix Band Sentinel-2 of Type B02_10m.tif

    printf("Enter path to list files: ");
    scanf("%s", path);
    printf("Enter the wildcard: ");
    scanf("%s", suffix);

    Node *B02_head;
    Node *SCL_head;
    B02_head = listFilesRecursively(path, suffix);
    char *suffix_scl = "SCL_10m.tif";
    SCL_head = listFilesRecursively(path, suffix_scl);
    show(B02_head);
    show(SCL_head);
    return 0;
}
包括
#包括
#包括
#包括
#包括“gdal/gdal.h”
#包括“gdal/cpl_conv.h”
#包括
#包括
//链表的节点结构
类型定义结构列表{
字符*数据;
结构nlist*next;
}节点;
//函数将字符串替换为另一个字符串
//串
char*str_替换(char*string,const char*substr,const char*replacement){
char*tok=NULL;
char*newstr=NULL;
char*oldstr=NULL;
int oldstr_len=0;
int substr_len=0;
整数替换_len=0;
newstr=strdup(字符串);
substr_len=strlen(substr);
更换=斯特伦(更换);
if(substr==NULL | | replacement==NULL){
返回新闻TR;
}
而((tok=strstrstr(newstr,substr))){
oldstr=newstr;
oldstr_len=strlen(oldstr);
newstr=(char*)malloc(sizeof(char)*(oldstr_len-substr_len+replacement_len+1));
if(newstr==NULL){
免费(oldstr);
返回NULL;
}
memcpy(newstr、oldstr、tok-o