分段故障检查strcmp

时间:2017-02-17 23:13:03

标签: c segmentation-fault strcmp dirent.h

我正在编写一个函数next_node,用于查找目录中的下一个文件。 node将目录和文件名作为输入。

如果NULL之后没有其他文件,或者bname".",我希望它返回".."。它仅在segmentation fault (core dumped)语句if内运行时才会strcmp

您能解释一下问题或提供解决方案吗?

代码:

#include <stdio.h>
#include <dirent.h> // DIR opendir() closedir() struct dirent readdir()
#include <string.h> // strcmp()

char *next_node(char *dname, char *bname) {
    if (!strcmp(dname, bname)) {
        // dname same as bname
        return NULL;
    }
    DIR *dirp = opendir(dname);
    struct dirent *direntp;
    while (((direntp = readdir(dirp)) != NULL) && (strcmp(direntp->d_name, bname))) {
    }
    if ((direntp = readdir(dirp)) != NULL) {
        // if d_name is "." or ".." return NULL
        if ((strcmp(direntp->d_name, ".")) || (strcmp(direntp->d_name, ".."))) {
            return NULL;
        }
        // it can reach here with no problem
        closedir(dirp);
        return direntp->d_name;
    } else {
        closedir(dirp);
        return NULL;
    }
}

int main() {
    char *dname = ".";
    char *bname = "test.c";
    char *result = next_node(dname, bname);
    printf("%s\n", result);
    return 0;
}

3 个答案:

答案 0 :(得分:3)

你有五个错误。

1:

DIR *dirp = opendir(dname);

您不会检查此opendir是否成功。

2:

struct dirent *direntp;
while (((direntp = readdir(dirp)) != NULL) && (strcmp(direntp->d_name, bname))) {
}
if ((direntp = readdir(dirp)) != NULL) {

在这里,即使前一个循环因为readdir返回readdir而终止,也会调用NULL。你想要:

if ((direntp != NULL) && ((direntp = readdir(dirp)) != NULL)) {

3:

    if ((strcmp(direntp->d_name, ".")) || (strcmp(direntp->d_name, ".."))){

将整数转换为布尔值等同于询问它是否不为零。 strcmp函数在匹配时返回零。因此,询问它是否为零是在询问它是否匹配。但是一切都不是“匹配”。或者不是“......”的匹配!你想要:

    if ((!strcmp(direntp->d_name, ".")) || (!strcmp(direntp->d_name, ".."))){

4:

    // it can reach here with no problem
    closedir(dirp);
    return direntp->d_name;

您刚刚将指针返回到已关闭的目录,导致指针无效。您需要确定返回指针的生命周期应该是什么,并且可能会分配一些内存来返回。

也许:

    char *ret = strdup (dirent->d_name);
    closedir(dirp);
    return ret;

请注意,调用者完成后需要free返回的字符串。

5:

char *result = next_node(dname, bname);
printf("%s\n", result);

如果resultNULL,则会失败。尝试:

char *result = next_node(dname, bname);
printf("%s\n", (result == NULL) ? "NULL" : result);

答案 1 :(得分:0)

(代表OP发布)

更新:问题是在main中打印NULL。打印NULL仅在Linux中提供segfault,而不是Windows。

答案 2 :(得分:-1)

strcmp返回0如果它们之间没有区别,请尝试以下代码

if (strcmp(dname, bname)) {
    return NULL;
}

编辑:我也不确定您的问题是我在Windows上使用gcc进行编译,并且我没有遇到任何问题。