malloc, free 버그 좀 찾아주세요.
글쓴이: powerc20 / 작성시간: 화, 2006/02/14 - 6:40오후
아래 코드를 실행하면 i386 Redhat ES에서 실행하면,
Segmentation fault (core dumped)
에러가 납니다.
free의 순서에 따라
*** glibc detected *** double free or corruption (!prev): 0x09496110 ***
위 에러가 발생하기도 합니다.
제 생각에는 문제가 없는 코드이 것 같은데 에러가 발생해서 여러가지 문서를 찾아 봤으나 해결책을 모르겠습니다.
고수님들의 지도 바랍니다.
ps) 아래 코드는 두개의 파일을 open해서 제가 원하는 형태로 조합한 하나의 파일을 만드는 코드입니다.
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <errno.h> #define NUMBERS_OF_IDS 369 #define EXT_NAME ".id" #define DATA_4BYTE_ALIGN (~0x3) #define DATA_STATR_POSITION ( (NUMBERS_OF_IDS * 2 + 3) & DATA_4BYTE_ALIGN ) typedef signed char CHAR; typedef unsigned char UCHAR; typedef signed short INT16; typedef unsigned short UINT16; typedef signed int INT32; typedef unsigned int UINT32; int main(int argc, char *argv[]) { INT32 input_fd, output_fd, sizefile_fd; // file descriptor UCHAR *source, *target, *size; // address by mmap UCHAR *source_temp, *target_temp, *size_temp; // address by mmap UCHAR *output_filename; UINT16 count = 0, filesize = 0, length = 0, size_filesize = 0; UINT16 id_position = 0, data_position = DATA_STATR_POSITION, old_data_position; UCHAR value, sum_of_width = 0; if( argc != 3) { printf("Usage : ./id input_file_name size_file_name\n"); exit(-1); } /* input file open argv[1] */ if ( (input_fd = open(argv[1], O_RDONLY)) == -1) { perror("open input file"); exit(-1); } if( (output_filename = (UCHAR *)malloc( 256 * sizeof(UCHAR) )) == NULL) { perror("malloc output_filename"); exit(-1); } if( (target = (UCHAR *)malloc ( NUMBERS_OF_IDS * 2 + filesize/2 + 1 )) == NULL) { perror("malloc target"); exit(-1); } /* output file name making .src -> .id */ strncpy(output_filename, argv[1],20); for(count = 0 ; count < 256 ; count++) if(output_filename[count] == '.') { output_filename[count] = '\0'; break; } strcat(output_filename,EXT_NAME); if ( (output_fd = open(output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0664)) == -1) { perror("open output file"); exit(-1); } /* find filesize by seek to SEEK_END */ filesize = lseek(input_fd, 0, SEEK_END ); /* size file open */ if ( (sizefile_fd = open(argv[2], O_RDONLY )) == -1) { perror("open size file"); exit(-1); } /* source file mmap */ if ( ( source = mmap(0, filesize, PROT_READ, MAP_SHARED, input_fd, 0) ) == (void *)-1) { perror("mmap source"); exit(-1); } /* find filesize by seek to SEEK_END */ size_filesize = lseek(sizefile_fd, 0, SEEK_END ); /* size file mmap */ if ( ( size = mmap(0, size_filesize, PROT_READ, MAP_SHARED, sizefile_fd, 0) ) == (void *)-1) { perror("mmap size"); exit(-1); } source_temp = source; target_temp = target; size_temp = size; for(count = 0 ; count < NUMBERS_OF_IDS ; count++) { id_position = count * 2; *( (UINT16 *) (target_temp + (id_position)) ) = data_position ; /* id length position */ old_data_position = data_position; /* id length position reserved */ data_position += 2; do { while( length < 2 ) { if( ( *(source_temp) >= '0' && *(source_temp) <= '9' ) ) { if(length == 0) { value = (*source_temp - 48) * 16; } else if(length == 1) { value += *source_temp - 48; } } else if( *(source_temp) >= 'a' && *(source_temp) <= 'f' ) { if(length == 0) { value = (*source_temp - 87) * 16; } else if(length == 1) { value += *source_temp - 87; } } else if( *(source_temp) >= 'A' && *(source_temp) <= 'F' ) { if(length == 0) { value = (*source_temp - 55) * 16; } else if(length == 1) { value += *source_temp - 55; } } else { source_temp++; continue; } source_temp++; length++; } length = 0; if(value != 0) { *(target_temp + data_position) = value; data_position++; sum_of_width += size[value]; printf("sum of width : %d, size[value] : %d , value : %d\n", sum_of_width, size[value], value); } } while(value != 0x00); *(target_temp + old_data_position) = data_position - old_data_position - 1; *(target_temp + old_data_position +1) = sum_of_width; sum_of_width = 0; } write(output_fd, target_temp, data_position); printf("%s is converted to %s successfuly.\n", argv[1], output_filename); munmap(source, filesize); munmap(size, size_filesize); free((void *)output_filename); free((void *)target); close(input_fd); close(output_fd); close(sizefile_fd); return 0; }
실행법
첨부된 화일의 압축을 해제하면 korean.src와 size가 있습니다.
#./id korean.src size
즐거운 하루 되세요.
ps) 코드 태그가 뭔지 몰라서 우선 이렇게 올립니다. 20분 정도 검색을 했는데 잘 모르겠습니다. 첨부 화일 올리는것도 한 10분 정도 헤맸네요. ㅡㅡ;; 코드 태그 올리는 방법을 알려주시면 바로 수정해서 올리겠습니다.
File attachments:
첨부 | 파일 크기 |
---|---|
input.tar | 10 KB |
Forums:
Electric fence류의 프로그램을 써보시는 것은 어떨까요?
Electric fence류의 프로그램을 써보시는 것은 어떨까요?
세그폴트가 어디서 떨어지는지를 알려주시면 큰 도움이 될 것 같습니다만..
세그폴트가 어디서 떨어지는지를 알려주시면 큰 도움이 될 것 같습니다만...?? :)
----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------
1. code 태그를 사용해 주시고2. 예제 인풋 파일들도 함께 올려
1. code 태그를 사용해 주시고
2. 예제 인풋 파일들도 함께 올려주세요.
이렇게 올려주시면 아무도 읽을 마음이 안생기실겁니다 :-(
----
Let's shut up and code.
댓글 달기