const char * 형식의 인수를 갖는 함수를 재귀호출하면 문제가 생기는 가요 ?
글쓴이: parkon / 작성시간: 화, 2013/09/17 - 3:37오후
CERN에서 개발된 ROOT라는 툴킷(라이브러리)를 가지고 작업 중입니다.
제가 짜려고 하는 루틴은
디렉토리 명을 인수를 받아
그 안에 있는 파일들 중, 원하는 데이타 형식을 가진 녀석들을 저의 DB속에 집어 넣는 일인데,
서브 디렉토리들을 가질 수도 있어 재귀적 호출을 해야 하고,
그 중 어떤 파일이나 섭 디렉토리가 zip을 압축되어 있어 zip 확장자를 가진 녀석을 만나면
이들을 임시 디렉토리에 푼 다음 풀어진 파일들도 검색하는 일입니다.
즉 이 루틴을 void foo(const char* path)라고 한다면 대충 구조는 다음과 같습니다.
void foo(const char* path) { printf("For check 1: %s\n", path); // for check if (path가 디렉토리 명이 아닌가 ?) return; TList *files = (path 밑의 파일이름들에 대한 리스트); TSystemFile *file; // 하드디스크 상의 파일 혹은 디렉토리에 대한 클래스 인스턴스의 포인터 TIter next(files); int nzip = 0; // 임시 디렉토리에 압축을 푼 zip 파일 갯수 while ((file=(TSystemFile*)next())) { printf("For check 2: %s\n", path); // for check if (file의 이름이 "." 혹은 ".."인가?) continue; TString fname = Form("%s%s", path, file->GetName()); // path 정보를 포함한 파일 명 if (fname이 디렉토리 명인가 ?) { foo(fname.Data()); // 재귀호출 } else if (파일확장자가 zip인가?) { TString unzip_dir = "/tmp/foo_tmp"; // 실제론 유일한 새 디렉토리를 만들기 위해 좀 복잡함. if (nzip == 0) { // 압축을 풀 임시 디렉토리 생성 및 확인 } gSystem->Exec(Form("unzip %s -d %s", fname.Data(), unzip_dir.Data())); // 압축 풀기 } else if (원하는 형식의 데이타 파일인가 ?) { do_my_job(fname.Data()); } } if (nzip > 0) { // 압축을 푼 파일들이 있다면 foo(unzip_dir.Data()); // 임시 디렉토리에 대한 작업 실시 임시 디렉토리 삭제; printf("For check 3: path = %s\n", path); // for check } }
이런 식인데요,
이게 어떤 때는 원하는 대로 잘 됩니다.
근데 어떤 때는 const char*로 정의된 저 path의 내용이 달라져 버리는 군요.
즉 잘 나가다가, 중간 쯤에서, path의 내용이
원래 path명과 파일 명들의 이상하게 조합되어서 적당히 짤린 이름으로 대체되어 버리는 현상이 생깁니다.
특히 임시 디렉토리 생성/처리/삭제 후에,
check 3에서는 정상적으로 보이는 데 그 다음 check 2에서는 이상한 이름으로 바뀌어 있는 경우가
발생합니다.
이 문제로 며칠을 끙끙거리고 있는데 혹시 짐작가시는 데 있으시면 조언 부탁 드립니다.
혹시, 뭔가 말이 안되는 것 같지만, const char* 형식의 인수를 가진 함수는 재귀호출할때
무슨 문제가 있거나 아님 다른 주의점 같은데 있으려나요 ?
Forums:
포인터를 인수로 넘긴다는 것은
값을 넘기는 것이 아니라 주소를 넘기는 것으로 압니다. 함수의 인수로 주소를 넘길 수 있죠. 타입이 차원이 같은 포인터 변수라면 가능합니다.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
...?
올려주신 프로그램은 실제 프로그램과 다르군요. 현재 형태로는 foo(unzip_dir.Data())를 부르기 전에 unzip_dir 변수가 사라져 버리므로 컴파일이 안될 텐데요.
실제로 돌아가고 실제로 문제가 발생하는 소스를 올려주세요. 그래야 뭐가 문제가 있는지 알죠.
말씀하신게 맞습니다. 실제 코드에서는
말씀하신게 맞습니다. 실제 코드에서는 unzip_dir이 저 루프 외부에 정의되어 있구요.
근데 실제 코드를 다 올리기엔 너무 지저분하고 길어서요...,
이 글 올리고 난 후 다시 몇가지 시도를 해 봤는데
위 프로그램을 돌리는 cint 마크로 파일에서
예를 들어
이렇게 하면 생기던 문제들 중 상당수가
이렇게 하면 해결되는데, 감을 잘 못잡겠네요.
위의 foo 함수가 아닌 다른 곳에서 어떤 이상한 일이 일어나고 있다는 반증일까나요 ?
path.Data()가 null termination
path.Data()가 null termination 이 안되는 것 아닐까요? foo 함수의 인자로 뭐가 들어오는지 한 번 보시죠.
댓글 달기