malloc, free 버그 좀 찾아주세요.

powerc20의 이미지

아래 코드를 실행하면 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.tar10 KB
kewlbear의 이미지

Electric fence류의 프로그램을 써보시는 것은 어떨까요?

kuaaan의 이미지

세그폴트가 어디서 떨어지는지를 알려주시면 큰 도움이 될 것 같습니다만...?? :)

----------------------------------------------
한번뿐인 인생....
미친듯이 살아보자!
----------------------------------------------

sangwoo의 이미지

1. code 태그를 사용해 주시고
2. 예제 인풋 파일들도 함께 올려주세요.

이렇게 올려주시면 아무도 읽을 마음이 안생기실겁니다 :-(

----
Let's shut up and code.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.