[英]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
. 它仅在strcmp
的if
语句中运行时才给我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
. 如果result
为NULL
则将失败。 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.