char** 分配以及如何存储值

标签 c segmentation-fault

    void allocateFolderTree(char **tree)
    {
        int i;
        tree = (char **)malloc(sizeof(char*)*MAX_FOLDERS);
        for(i=0;i<MAX_FOLDERS;i++)
          tree[i] = (char *)malloc(sizeof(char)*MAX_FOLDERS*MAX_FILENAME);    
    }

    void getFolderTree (char **tree, char *path, int i)
    {
        DIR *dir = opendir(path);
        struct dirent *entry;
        while (entry = readdir(dir)) 
        {
        if( !strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
            continue;   

        if (entry->d_type & DT_DIR)//check file type
        {
            //segfault for the next 3 lines
            strcpy(tree[i], path);
            strcat(tree[i], "/");
            strcat(tree[i], entry->d_name);

            i++;

            char *new_path = malloc(sizeof(char)*(strlen(path)+MAX_FILENAME));
            strcpy(new_path, path);
            strcat(new_path, "/");
            strcat(new_path, entry->d_name);
            getFolderTree(tree, new_path, i);
            free(new_path);
        }
        }
        closedir (dir);
    }

int main ()
{
    char **folderTree;
    allocateFolderTree(folderTree);
    getFolderTree(folderTree, ROOT, 0);

    free(folderTree);
    return 0;
}

为什么我会出现段错误以及如何解决这个问题?

PS: 最大文件夹数=1000 最大文件名=30 我正在读取的文件夹少于 10 个,每个文件夹的名称少于 30 个!

最佳答案

这段代码:

void allocateFolderTree(char **tree)
{
    int i;
    tree = (char **)malloc(sizeof(char*)*MAX_FOLDERS);
    for(i=0;i<MAX_FOLDERS;i++)
      tree[i] = (char *)malloc(sizeof(char)*MAX_FOLDERS*MAX_FILENAME);    
}

在函数中修改了tree的本地副本,但从未将其返回给调用代码,因此分配的内存在函数返回后立即全部丢失。对于如何解决此问题,您至少有两种选择:

char **allocateFolderTree(void)
{
    int i;
    char **tree = (char **)malloc(sizeof(char*)*MAX_FOLDERS);
    for(i=0;i<MAX_FOLDERS;i++)
      tree[i] = (char *)malloc(sizeof(char)*MAX_FOLDERS*MAX_FILENAME);
    return tree;  
}

或者:

void allocateFolderTree(char ***tree)
{
    int i;
    *tree = (char **)malloc(sizeof(char*)*MAX_FOLDERS);
    for(i=0;i<MAX_FOLDERS;i++)
      (*tree)[i] = (char *)malloc(sizeof(char)*MAX_FOLDERS*MAX_FILENAME);    
}

总的来说,避免三重指针是一个好主意,所以我通常会选择其他选项。

我还观察到所有循环都在内循环中分配了很多空间。您确定要在大小中包含 MAX_FOLDERS 吗?从表面上看,您应该分配 MAX_FILENAME 的大小,而不是 MAX_FOLDERS * MAX_FILENAME。 (每个内部分配当前分配大约 30 KiB,因此总共分配大约 30 MiB 空间。)

请注意,根据定义,sizeof(char) == 1,因此几乎不需要将其包含在大小计算中。

关于char** 分配以及如何存储值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22443767/

相关文章:

c - 如何设置相机的fps?

c - 为什么 C 中可以有一个指向字符串数组的指针

ubuntu - vscode 没有运行并给出段错误

c - fgets() 在 C 中从 stdin 接收输入的段错误

c# - 托管语言如何确保没有段错误

c - 访问 C 结构中的变量

c - 短数组的最佳排序函数

python - 使用 MinGW C 编译器代替 Microsoft Visual Studio Express for Python

c - strcpy() 中的段错误

c - 仅在打印时出现段错误