You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言:函数外无法读取字符串数组,程序崩溃原因求助

问题解析:为什么scanDir返回后主函数访问files会崩溃?

你碰到的这个问题本质是C语言里参数值传递的坑——哪怕你传的是char**,在scanDir里修改的也只是这个指针的副本,根本影响不到main函数里最初的files变量。

具体来捋一遍:

  1. 在main里你初始化了char** files = 0;,调用scanDir(files, ...)的时候,函数的形参files是一个全新的变量,它只是复制了main中files的初始值(NULL)。
  2. 当你在scanDir里执行files = malloc(...)或者files = realloc(...)时,你只是改变了这个形参files自己的指向,和main里的那个files半毛钱关系都没有。
  3. 等scanDir执行完返回,main里的files还是最初的NULL,你接着去访问files[i],这不就是访问空指针嘛,程序不崩溃才怪。

怎么解决?有两种靠谱的方式:

方法一:用三级指针传参

把scanDir的参数改成char*** files,这样就能在函数内部直接修改main里files的指向:

#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>

int scanDir(char*** files, char* path) {
    int size = 0, i = 0;
    DIR* dp = NULL;
    struct dirent* ep = NULL;
    *files = NULL; // 初始化外部指针为NULL
    dp = opendir(path);
    if (dp != NULL) {
        // 明确判断readdir的返回值是否为NULL,避免逻辑隐患
        while ((ep = readdir(dp)) != NULL) {
            // 重新分配内存,修改的是main中files的实际指向
            *files = realloc(*files, sizeof(char*) * (size + 1));
            (*files)[i] = malloc(sizeof(char) * (strlen(ep->d_name) + 1));
            strcpy((*files)[i], ep->d_name);
            size++;
            i++;
        }
        closedir(dp);
    }
    return size;
}

int main(void) {
    char** files = NULL;
    int size = 0, i = 0;
    // 传files的地址给scanDir
    size = scanDir(&files, "C:\\Users\\user\\test");
    for (i = 0; i < size; i++) {
        puts(files[i]);
        free(files[i]);
    }
    free(files);
    getchar();
    return 0;
}

方法二:让函数直接返回分配好的char**

这种写法更直观,把分配好的指针直接返回给main函数,同时用指针参数带回文件数量:

#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>

char** scanDir(char* path, int* size) {
    char** files = NULL;
    int i = 0;
    DIR* dp = NULL;
    struct dirent* ep = NULL;
    *size = 0;
    dp = opendir(path);
    if (dp != NULL) {
        while ((ep = readdir(dp)) != NULL) {
            files = realloc(files, sizeof(char*) * (*size + 1));
            files[i] = malloc(sizeof(char) * (strlen(ep->d_name) + 1));
            strcpy(files[i], ep->d_name);
            (*size)++;
            i++;
        }
        closedir(dp);
    }
    return files;
}

int main(void) {
    char** files = NULL;
    int size = 0, i = 0;
    // 直接接收返回的指针,同时传入size的地址获取文件数量
    files = scanDir("C:\\Users\\user\\test", &size);
    for (i = 0; i < size; i++) {
        puts(files[i]);
        free(files[i]);
    }
    free(files);
    getchar();
    return 0;
}

最后提个小细节:

原来的代码里while (ep = readdir(dp))最好改成while ((ep = readdir(dp)) != NULL),虽然在大多数情况下前者也能工作,但后者更严谨,能明确判断目录读取结束的条件。

内容的提问来源于stack exchange,提问作者Daniel.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:28:29