fclose ()가 분할 결함을 일으키는 것을 유발합니다
-
22-07-2019 - |
문제
내가 구문 분석하는 탭으로 변형 된 텍스트 파일이 있습니다. 첫 번째 열에는 형식의 문자열이 포함되어 있습니다 chrX
, 어디 X
문자열 세트 (예 : "1", "2", ..., "x", "y"를 나타냅니다.
이들은 각각 a에 저장됩니다 char*
~라고 불리는 chromosome
, 파일이 구문 분석 할 때.
텍스트 파일은 첫 번째 열 사전에 정렬되어 있습니다. 즉, "chr1"으로 시작하여 "chr2"등으로 시작하는 여러 행이 있습니다.
각 "chrx"항목 에서이 항목과 관련된 다른 파일을 열어야합니다.
FILE *merbaseIn;
// loop through rows...
if (chromosome == NULL)
openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN);
else {
if (strcmp(chromosome, fieldArray[i]) != 0) { // new chromosome
fclose(merbaseIn); // close old chromosome FILE ptr
free(chromosome); // free old chromosome ptr
openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN); // set up new chromosome FILE ptr
}
}
// parse row
나는 기능이있다 openSourceFile
다음과 같이 정의됩니다.
void openSourceFile (char** chrome, const char* field, FILE** filePtr, const char *path) {
char filename[100];
*chrome = (char *) malloc ((size_t) strlen(field));
if (*chrome == NULL) {
fprintf(stderr, "ERROR: Cannot allocate memory for chromosome name!");
exit(EXIT_FAILURE);
}
strcpy(*chrome, field);
sprintf(filename,"%s%s.fa", path, field);
*filePtr = fopen(filename, "r");
if (*filePtr == NULL) {
fprintf(stderr, "ERROR: Could not open fasta source file %s\n", filename);
exit(EXIT_FAILURE);
}
}
문제는 내 응용 프로그램이 첫 번째 염색체에서 두 번째로 세그먼테이션 오류가 발생한다는 것입니다. chr1
에게 chr2
) 다음 줄에서 열린 첫 번째 염색체 파일을 닫습니다.
fclose(merbaseIn);
나는 내가 지나지 않는다는 것을 안다 fclose
NULL 포인터는 세그먼트 화 결함까지 올라가기 때문에이 파일에서 데이터를 읽고 있습니다. 나는 이것을 조건부로 마무리 할 수도 있고 여전히 결함을 얻습니다.
if (merbaseIn != NULL) {
fclose(merbaseIn);
}
또한, 나는 알고있다 openSourceFile
작동합니다 (적어도 chr1
, 첫 번째 파일 핸들을 설정할 때 FILE*
) 내 신청서가 구문 분석하기 때문입니다 chr1
행에서 데이터를 읽고 읽습니다 FILE*
소스 파일을 올바르게합니다.
이것에 대해 무엇입니까? fclose
세분화 결함이 발생하는 호출?
해결책
valgrind --db-attach=yes --leak-check=yes --tool=memcheck --num-callers=16 --leak-resolution=high ./yourprogram args
Segfault는 현지인에게 영향을 미치는 것이 아니라 힙의 기억 부패로 인해 발생할 가능성이 높습니다. Valgrind 즉시 당신이 만든 첫 번째 잘못된 액세스를 보여줄 것입니다.
편집 : --db-attach
옵션 valgrind
2014 년 릴리스 3.10.0 이후 더 이상 사용되지 않았습니다. 릴리스 노트 상태 :
The built-in GDB server capabilities are superior and should be used
instead. Learn more here:
http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver
다른 팁
내가 알아 차린 한 가지 오류는 다음 줄입니다.
*chrome = (char *) malloc ((size_t) strlen(field));
해야 할 것이다 :
*chrome = (char *) malloc ((size_t) strlen(field)+1);
문자열에는 끝에 닫는 0이 있기 때문에
가장 좋은 추측은 코드의 다른 부분이 버퍼 오버런 또는 유사한 버그를 통해 메모리를 손상시키는 것입니다.
원인이 될 가능성은 거의 없지만 전체 파일 이름이 100 숯을 초과 할 때 파일 이름 배열에 잠재적 인 오버런 조건이 있습니다.
Debugger를 사용하여 Merbasein 변수가 사용하는 메모리 위치의 변경 사항을 관찰하는 것이 좋습니다.
일반적인 포인터 문제
C는 훌륭한 언어이지만 자신의 기억을 막지 않아야합니다. Malloc이 1 바이트가 짧은 곳에 이전에 언급 된 문제 외에도 다른 포인터 문제가있을 수 있습니다.
내가 제안 할게 메모리 디버거 사용. 과거에, 전기 울타리 다소 인기가 있었지만 요즘 나는 Valgrind에 대해 더 많이 들어보십시오. 다른 많은 선택이 있습니다.
발견 한 오류 외에도 Reinier, 나는 다음과 같습니다.
free(chromosome);
뒤 따르는 것 :
chromosome = NULL;
더 이상 유효한 가치가없는 잠재적 사용을 방지하기 위해.
이 파일 ** FilePtr만이 파일* FilePtr 만 충분한 이유는 무엇입니까? 그냥 생각 ...
valgrind
~와 함께 memcheck
분명히 분할 결함의 원인을 발견 할 수있는 올바른 도구입니다. 디버거를 사용합니다 valgrind
, --db-attach
옵션 valgrind
Valgrind 3.10.0이 2014 년에 출시 된 이후 더 이상 사용되지 않았습니다. 릴리스 노트 상태 :
The built-in GDB server capabilities are superior and should be used
instead. Learn more here:
http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver
사용한 모든 장소를 검토하십시오 "Malloc" 그리고 당신이 실수를했는지 확인하십시오.
예를 들어, 나는 파일에서 char **에 라인을 읽고 있었지만 다음과 같이 잘못 만들었습니다.
my_list = malloc(sizeof(char) * num_lines_found_in_file);
그럴 때 :
my_list = malloc(sizeof(char*)* num_lines_found_in_file);