Linux下C语言递归遍历目录出现Segmentation fault(core dumped)求助
Alright, let's walk through the common issues in your code snippet that could be causing that segmentation fault, plus concrete fixes to get your recursive directory lister working.
1. You're not checking if malloc succeeds
If malloc returns NULL (due to low memory), any subsequent operations on name will immediately trigger a segfault. Always validate dynamic allocations:
char *name = malloc(sizeof(char) * MAX_LEN); if (!name) { perror("Failed to allocate memory for path"); closedir(dir); // Clean up if dir was already opened return; }
2. You're not skipping . and .. directories
Without skipping the current directory (.) and parent directory (..), your function will recurse infinitely. This blows up the call stack, leading to a segfault. Add this check inside your while loop:
while((dirent = readdir(dir)) != NULL) { // Skip self and parent to avoid infinite recursion if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) { continue; } // Rest of your path handling here }
3. Unsafe path concatenation (likely the culprit)
If you're using strcat or manual string copying to build the new path for recursion, you're at risk of buffer overflow (since paths can exceed MAX_LEN). Use snprintf instead—it safely limits the output to your buffer size, and lets you check for overflow:
// Build the full path safely int ret = snprintf(name, MAX_LEN, "%s/%s", path, dirent->d_name); if (ret >= MAX_LEN) { fprintf(stderr, "Error: Path %s/%s exceeds maximum length (%d)\n", path, dirent->d_name, MAX_LEN); continue; // Skip this entry instead of crashing } // Now call recursively list_recursive(name);
4. Forgetting to clean up resources
Leaving DIR* handles open or failing to free name won't directly cause a segfault, but it leads to resource leaks that can cause issues over time. Always clean up before returning:
if (dir != NULL) { closedir(dir); } free(name); // Free the malloc'd buffer regardless of success
5. Edge case: Deep directory trees
If you're dealing with extremely deep directory structures, recursive calls can exhaust the stack memory (another cause of segfaults). For this scenario, switch to an iterative approach using a stack/queue data structure to track directories to process, instead of relying on the call stack.
Quick Full Fix Snippet
Here's how your function might look with all these fixes applied:
#define MAX_LEN 2048 void list_recursive(char* path){ DIR* dir; struct dirent *dirent; char *name = malloc(sizeof(char) * MAX_LEN); if (!name) { perror("malloc failed"); return; } dir = opendir(path); if(dir != NULL){ printf("Directory: %s\n", path); while((dirent = readdir(dir)) != NULL) { if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) { continue; } int ret = snprintf(name, MAX_LEN, "%s/%s", path, dirent->d_name); if (ret >= MAX_LEN) { fprintf(stderr, "Path too long: %s/%s\n", path, dirent->d_name); continue; } list_recursive(name); } closedir(dir); } else { // Handle case where path is a file (not a directory) or can't be opened printf("File: %s\n", path); } free(name); }
内容的提问来源于stack exchange,提问作者ISimion

