2011-09-10 3 views
1

주어진 디렉터리의 내용을 반환하는 함수가 필요합니다. 이를 위해 dirent.h에서 scandir을 사용하고 있습니다. 아래의 코드는 성공적으로 컴파일되고 (gcc -Wall test.c), 마지막 printf는 분할 오류로 연결됩니다. 이것은 "eps"구조 (dirent 구조체에 대한 포인터 배열에 대한 포인터)가 함수 뒤에 여전히 비어 있음을 의미합니다. 어떻게 해결할 수 있습니까?C에서 함수의 인수로 전달할 때 포인터 배열에 대한 포인터의 대상을 수정하십시오.

#include <stdlib.h> 
#include <stdio.h> 
#include <dirent.h> 
#include <string.h> 

static int myselector(const struct dirent * dir_entry) 
{ 
    char * pch = strstr(dir_entry->d_name, "."); 
    return pch == NULL ? 1 : 0; 
} 

int list_dir(char * dirname, struct dirent ** eps) 
{ 
    int nbfiles = scandir(dirname, &eps, myselector, alphasort); 
    if(nbfiles > 0) 
    { 
    printf("inside function: %s\n", eps[0]->d_name); 
    return 1; 
    } 
    else 
    return 0; 
} 

int main(int argc, char *argv[]) 
{ 
    int status = 0; 
    struct dirent ** eps = NULL; 
    status = list_dir("/home", eps); 
    if (status) 
    { 
    puts("ok"); 
    printf("outside function: %s\n", eps[0]->d_name); 
    } 
    return EXIT_SUCCESS; 
} 

답변

1

포인터가 변경되었습니다, 당신은 main()에 잘못된 것은보고있는 : 당신은 scandir()에 대한 포인터에 대한 포인터에 대한 포인터를 전달하는

때문입니다. 포인터에 대한 포인터가 가리키고있는 것을 변경하고 있습니다 (나는 아,니다 ...).

함수에서 &eps으로 scandir()을 호출하기 때문에 함수 밖에서 변경 내용이 손실됩니다. 함수 내에서 eps 값이 변경되었습니다.

int list_dir(char * dirname, struct dirent *** eps) 
{ 
    int nbfiles = scandir(dirname, eps, myselector, alphasort); 
    if(nbfiles != -1) 
    { 
    printf("inside function: %s\n", (*eps)[0]->d_name); 
    return 1; 
    } 
    else 
    return 0; 
} 
:

... 
printf("%p\n", eps); 
int nbfiles = scandir(dirname, &eps, myselector, alphasort); 
printf("%p\n", eps); 
... 

이가 여러분의 기능을 변경 수정하려면 :

더 나은 이것을 이해하려면

는, 현재의 기능에 eps에 포함 된 값이 무엇인지를 보여주는 printf() 문으로 scandir() 전화를 포장

그리고로 전화를 ...

status = list_dir("/home", &eps); 

: main(). 그런 다음 완벽하게 작동합니다

브로치 @ 바퀴벌레 - VirtualBox를 : ~ 함수 내에서 $ ./test
: struct dirent ***을 list_dir 브로치

+0

전형적인 "pointer-to-pointer-to ..."예제에서 명확한 답변 ... 내 머리에 새겨 넣어야합니다! – tflutre

1

당신은 경우 scandir 0을 반환, 즉, 빈 디렉토리를 포함하는 것 같지 않습니다. -1의 반환 값은 오류에만 해당됩니다.

+0

예,이 간단한 예는 약간 빠르며 지금 수정되었습니다. – tflutre

+0

segfault가 수정 되었습니까? –

+0

아니요. segfault는 입력 디렉토리가 비어있을 수 있기 때문에가 아니라 "eps"구조가 내 "listd_dir"함수 내에 채워지고 함수가 완료되면 비 웁니다. 그리고 나는 이것을 방지하는 방법을 모른다. – tflutre

1

만들기 대신 :
확인
외부 기능을 브로치 struct dirent **, scandir() 호출에서 & 연산자를 제거하고이를 main의 list_dir() 호출에 추가하십시오. list_dir의 첫 번째 라인()가 될 :

int list_dir(char * dirname, struct dirent *** eps) 
{ 
    int nbfiles = scandir(dirname, eps, myselector, alphasort); 

메인에서 list_dir() 호출된다 :

status = list_dir("/home", &eps); 

그 방법의 list_dir은() 위해 scandir()가 주에서 eps을 수정할 수 있습니다() list_dir()에 전달 된 스택의 인수를 수정하는 대신 주소를 통해.

+0

완벽한, 감사합니다! (그리고 유감스럽게도 대답을 선택하지 말라. Brian Roach는 몇 분 만에 더 빨랐다.) – tflutre

관련 문제