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

Linux tree工具实现代码在Gradescope深度目录测试中出现段错误求助

问题排查:实现tree工具时深度目录测试段错误

我实现了Linux的tree工具(用于打印命令行指定目录的子目录结构),但在Gradescope自动评分器的「1.8) Deep directory tree (0/5)」测试中失败,提示程序段错误(Program segfaulted),尽管代码能正确打印目录路径。我已将main函数中的char path[MAX_PATH_LEN]初始化为空字符串,但问题仍存在,代码如下:

/* problem1.c - implementation of Linux `tree` */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>

#define MAX_PATH_LEN 1024

void print_tree(const char *path, int indent) {
  DIR *dir;
  struct dirent *entry;

  if (!(dir = opendir(path))) {
    perror(path);
    return;
  }

  while ((entry = readdir(dir)) != NULL) {
    /* skip hidden files and directories */
    if (entry->d_name[0] == '.')
      continue;

    /* print indentation */
    for (int i = 0; i < indent; i++)
      putchar(' ');

    /* print directory or file name */
    printf("%s\n", entry->d_name);

    /* print subdirectories and files */
    if (entry->d_type == DT_DIR) {
      char subpath[MAX_PATH_LEN];
      snprintf(subpath, MAX_PATH_LEN, "%s/%s", path, entry->d_name);
      print_tree(subpath, indent + 4);
    }
  }

  closedir(dir);
}


int main(int argc, char* argv[])
{
    char path[MAX_PATH_LEN] = "";

    if (argc > 1) {
        /* use specified directory */
        strncpy(path, argv[1], MAX_PATH_LEN);
        printf("%s\n", path);
    } else {
        /* use current working directory */
        getcwd(path, MAX_PATH_LEN);
        printf(". \n");
    }

    print_tree(path, 4);

    return 0;
}

可能的问题与修复方案

1. strncpy未添加字符串终止符

strncpy不会自动在目标数组末尾添加\0,如果传入的argv[1]长度恰好等于MAX_PATH_LEN,path会变成无终止符的无效字符串。后续snprintf拼接路径时会读取越界内存,触发段错误。

修复:用snprintf替代strncpy,确保字符串始终以\0结尾:

if (argc > 1) {
    /* use specified directory */
    snprintf(path, MAX_PATH_LEN, "%s", argv[1]);
    printf("%s\n", path);
}

2. 递归栈溢出(深度目录场景)

每个递归调用的print_tree函数都会在栈上分配char subpath[MAX_PATH_LEN](1024字节),如果目录深度极大(比如数百层),栈内存会被耗尽,引发段错误。

修复:改用动态内存分配存储子路径,减少栈内存占用:

/* print subdirectories and files */
if (entry->d_type == DT_DIR) {
    char *subpath = malloc(MAX_PATH_LEN);
    if (!subpath) {
        perror("malloc failed");
        closedir(dir);
        return;
    }
    snprintf(subpath, MAX_PATH_LEN, "%s/%s", path, entry->d_name);
    print_tree(subpath, indent + 4);
    free(subpath);
}

或者直接增大MAX_PATH_LEN到系统标准的PATH_MAX(通常为4096),同时确保编译时定义正确:

#include <limits.h>
#define MAX_PATH_LEN PATH_MAX

3. d_type字段不可靠

部分文件系统(如NFS)不支持dirent->d_type字段,此时d_type会返回DT_UNKNOWN,导致无法递归处理目录。虽然这不一定直接引发段错误,但会导致功能异常,也可能间接引发问题。

修复:用stat函数判断是否为目录,增强兼容性:

#include <sys/stat.h>

// ...

if (entry->d_type == DT_DIR || entry->d_type == DT_UNKNOWN) {
    char subpath[MAX_PATH_LEN];
    snprintf(subpath, MAX_PATH_LEN, "%s/%s", path, entry->d_name);
    struct stat st;
    if (stat(subpath, &st) == 0 && S_ISDIR(st.st_mode)) {
        print_tree(subpath, indent + 4);
    }
}

内容的提问来源于stack exchange,提问作者anand pradeep kumar sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 15:41:27