#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#include "header.h"
char *ROOT = "/home/dereaper/Desktop/shared";
void getFolders (char *PATH, int i) {
const char *path = PATH;
DIR *dir = opendir(path);
struct dirent *entry;
while(entry = readdir(dir)) {
if(!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
continue;
printf("%s/%s INDEX:%d\n", path, entry->d_name, i);
if(entry->d_type & DT_DIR) { //check file type
char *new_path;
strcat(new_path, path);
strcat(new_path, "/");
strcat(new_path, entry->d_name);
getFolders(new_path, i+1); //segmentation fault when calling recursevly
// otherwise the program returns the correct output
}
}
closedir(dir);
}
为什么我会出现分段错误?
答案 0 :(得分:5)
char *new_path;
strcat(new_path, path);
是未定义的行为。
由于new_path未初始化且未分配,因此strcat没有内存可供追加。 strcat附加到未终止的地址,创建段错误。
答案 1 :(得分:2)
标准库函数strcat
的原型是
char *strcat(char *dest, const char *src);
此处,dest
和src
都是字符串,它们可能不重叠,dest
必须足够大,以便将src
指向的字符串附加到其上。
在您的代码中,在声明中
strcat(new_path, path);
new_path
是指向字符的指针,而不是字符串。它不会终止并且不足以使path
指向的字符串附加到它上面。 strcat
调用尝试非法内存访问导致由于段错误导致的未定义行为和程序崩溃。您必须动态或静态地分配缓冲区以将字符串连接到它。
#define MAX_LEN 40+1 // max buffer length. +1 for terminating null byte
char new_path[MAX_LEN] = {0}; // initialize to null bytes
strcat(new_path, path);
// more strcat calls
编辑如评论中所述,事先不知道最大缓冲区长度。在这种情况下,应使用calloc
和realloc
动态分配内存。
int size = strlen(path) + 1;
char *temp = NULL; // for holding new_path in case realloc fails
char *new_path = calloc(size, sizeof path[0]);
if(new_path == NULL) {
printf("Not enough memory.\n");
// handle it
}
strcat(new_path, path);
temp = new_path;
new_path = realloc(new_path, size *= 2); // double the size of the buffer
if(new_path == NULL) {
printf("Not enough memory.\n");
// handle it
}
// check if new_path is large enough for concatenation
const char *catstr = "somestring"; // string to be appended
if(size <= strlen(new_path) + strlen(catstr)) {
// allocate more memory
temp = new_path;
new_path = realloc(new_path, size *= 2); // double the buffer size
if(new_path == NULL) {
printf("Not enough memory.\n");
// handle it
}
}
strcat(new_path, catstr);
// and so on
NULL
的所有检查都变得笨拙,但在处理动态内存分配时,没有简单的方法。