[英]Segmentation fault checking strcmp
我正在編寫一個函數next_node
,該函數在目錄中查找下一個文件。 節點將目錄和文件名作為輸入。
如果bname
之后沒有其他文件或它是"."
我希望它返回NULL
"."
或".."
。 它僅在strcmp
的if
語句中運行時才給我segmentation fault (core dumped)
。
您能解釋這個問題或提供解決方案嗎?
碼:
#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;
}
你有五個錯誤。
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
返回NULL
終止,您也可以調用readdir
。 你要:
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);
如果result
為NULL
則將失敗。 嘗試:
char *result = next_node(dname, bname);
printf("%s\n", (result == NULL) ? "NULL" : result);
(代表OP張貼) 。
更新:問題是在main中打印NULL。 在Linux中,將NULL打印只會產生段錯誤,而在Windows中則不會。
strcmp返回0如果它們之間沒有區別,請嘗試以下操作
if (strcmp(dname, bname)) {
return NULL;
}
編輯:另外,我不確定您的問題是我正在Windows上使用gcc編譯此文件,還是沒有任何問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.