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
相关产品推荐
相关产品推荐

