简体   繁体   English

分段故障检查strcmp

[英]Segmentation fault checking strcmp

I am writing a function next_node that finds next file in the directory. 我正在编写一个函数next_node ,该函数在目录中查找下一个文件。 node takes a directory and a filename as input. 节点将目录和文件名作为输入。

I want it to return NULL if there is no other file after bname or if it is "." 如果bname之后没有其他文件或它是"."我希望它返回NULL "." or ".." . ".." It is giving me segmentation fault (core dumped) ONLY when it runs inside the if statement of strcmp . 它仅在strcmpif语句中运行时才给我segmentation fault (core dumped)

Can you explain the problem or give a solution please? 您能解释这个问题或提供解决方案吗?

Code: 码:

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

You have five mistakes. 你有五个错误。

1: 1:

DIR *dirp = opendir(dname);

You don't check if this opendir succeeds. 您无需检查此opendir成功。

2: 2:

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

Here, you call readdir even if the previous loop terminated because readdir returned NULL . 在这里,即使上一个循环由于readdir返回NULL终止,您也可以调用readdir You want: 你要:

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

3: 3:

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

Converting an integer to a boolean is equivalent to asking if it's not zero. 将整数转换为布尔值等效于询问其是否不为零。 The strcmp function returns zero on a match. strcmp函数在匹配时返回零。 So asking if it's not zero is asking if it's not match. 因此,询问是否不为零就是询问其是否匹配。 But everything is either not a match for "." 但是,一切都不是“。”的匹配项。 or not a match for ".."! 还是不匹配“ ..”! You want: 你要:

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

4: 4:

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

You just returned a pointer into a directory that you closed, rendering the pointer invalid. 您刚刚将指针返回到您关闭的目录中,从而使指针无效。 You need to decide what the lifespan of the returned pointer is supposed to be and perhaps allocate some memory to return. 您需要确定返回的指针的寿命是多少,并可能分配一些内存以返回。

Maybe: 也许:

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

Note that the caller needs to free the returned string when it's done with it. 请注意,调用者完成处理后需要free返回的字符串。

5: 5:

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

This will fail if the result is NULL . 如果resultNULL则将失败。 Try: 尝试:

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

(Posted on behalf of the OP) . (代表OP张贴)

Update: The problem was printing NULL in main. 更新:问题是在main中打印NULL。 Printing NULL only gives segfault in Linux but not Windows. 在Linux中,将NULL打印只会产生段错误,而在Windows中则不会。

strcmp returns 0 If there is no difference between them try the following instead strcmp返回0如果它们之间没有区别,请尝试以下操作

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

edit: also I'm not sure what you're issue is I'm compiling this using gcc on windows and i'm not having any issues with it. 编辑:另外,我不确定您的问题是我正在Windows上使用gcc编译此文件,还是没有任何问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM