无法找到发生分段错误的位置

时间:2014-03-16 18:36:43

标签: c

#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);
}

为什么我会出现分段错误?

2 个答案:

答案 0 :(得分:5)

char *new_path;
strcat(new_path, path);

是未定义的行为。

由于new_path未初始化且未分配,因此strcat没有内存可供追加。 strcat附加到未终止的地址,创建段错误。

答案 1 :(得分:2)

标准库函数strcat的原型是

char *strcat(char *dest, const char *src);

此处,destsrc都是字符串,它们可能不重叠,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

编辑如评论中所述,事先不知道最大缓冲区长度。在这种情况下,应使用callocrealloc动态分配内存。

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的所有检查都变得笨拙,但在处理动态内存分配时,没有简单的方法。