2014-02-24 4 views
0

안녕하세요, 저는 파일을 PFS 이미지로 압축해야하는 프로젝트를 진행하고 있습니다. 나는 ANSI C 언어를 사용하는 응용 프로그램을 작성 중이다. 각 파일에 Hexdump 및 다른 속성을 저장하고 내부 변수를 저장합니다.C 메모리 할당 오류

포장 된 파일에 대한 모든 정보가 수집되면 각 파일의 정보가 포함 된 출력 파일을 만들어야합니다.

이 작업을 수행함에 따라 메모리 할당에 문제가 있습니다. 오류를 출력하는 코드는 다음과 같습니다. 루프 위에서 채우고

for (Counter = 0; Counter < PackingCount; Counter ++) 
{ 
    PFSEntry Packed; 

    Packed.HexEquivalent = DumpHex(FileNames[Counter]); 

    strncpy(Packed.Filename, FileNames[Counter], NAME_BLOCK); 

    Packed.Offset = OffsetCounter; 

    OffsetCounter += FileSize; 

    Packed.FileSize = FileSize; 

    Packed.Timestamp = 2999606509; // For the Sake of Diffing 

    Packer[Counter] = Packed; 


} 

구조

typedef struct 
{ 
char Filename [NAME_BLOCK]; 
u_int32_t Timestamp; 
u_int32_t Offset; 
u_int32_t FileSize; 
char * HexEquivalent; 
} PFSEntry; 

아래에 도시되고, 다음과 같이 DumpHex 기능이다

char * DumpHex(char * FileName) 
{ 
    FILE * File = FileOpener(FileName, "rb"); 

    printf("%s is of Size %ld\r\n\r\n", FileName, FileSize); 

    fseek(File, 0L, SEEK_END); 

    FileSize = ftell(File); 

    fseek(File, 0L, SEEK_SET); 

    char * HexArray = malloc(FileSize); 

    unsigned char Character; 

    int Counter = 0; 

    while (Counter < FileSize) 
    { 
     Character = fgetc(File);  
     sprintf(HexArray + Counter, "%c", Character);  
     Counter++; 
    } 

    return HexArray; 
} 

의 육각 출력을 반환하는 함수 DumpHex, 주어진 파일이 다음 오류를 출력 중입니다.

의 a.out : malloc.c를 : 2,369 : sysmalloc 어설`(old_top == (((mbinptr) (((숯 *) & ((AV) -> 빈 [((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd))))) & & old_size == 0) || ((긴 부호) (old_size는)

= (부호 길이) ((((__ builtin_offsetof (구조체 malloc_chunk, fd_nextsize)) + ((2 * (는 sizeof (size_t로))) - 1)) &을 ~ ((2 * (는 sizeof (size_t로))) - 1))) & & ((old_top) -> &을 0x1 사이즈) & & ((부호 길이) old_end & pagemask) == 0) '실패. 중단 아래

가 발견 용액에 도움이 될 수 있습니다 응용 프로그램에 추가 된 일부 디버그 정보입니다 (코어 덤프).

Total Files to Pack 38 
Size of Packed Structure 80 
Packing File 0 of size 9319 Bytes 
Packing File 1 of size 1459 Bytes 
Packing File 2 of size 844 Bytes 
Packing File 3 of size 4396 Bytes 
Packing File 4 of size 270250 Bytes 
Packing File 5 of size 656800 Bytes 
Packing File 6 of size 0 Bytes 
Packing File 7 of size 322744 Bytes 
Packing File 8 of size 1278114 Bytes 
Packing File 9 of size 12473 Bytes 
Packing File 10 of size 13791 Bytes 
Packing File 11 of size 14158899 Bytes 
Packing File 12 of size 343051 Bytes 
Packing File 13 of size 599051 Bytes 
Packing File 14 of size 505867 Bytes 
Packing File 15 of size 10138349 Bytes 
Packing File 16 of size 17481 Bytes 
Packing File 17 of size 4900 Bytes 
Packing File 18 of size 9000 Bytes 
Packing File 19 of size 343 Bytes 
Packing File 20 of size 6888 Bytes 
Packing File 21 of size 13992 Bytes 
Packing File 22 of size 916222 Bytes 
Packing File 23 of size 2048 Bytes 
Packing File 24 of size 7776 Bytes 
Packing File 25 of size 13884 Bytes 
Packing File 26 of size 10787 Bytes 
Packing File 27 of size 12747 Bytes 

a.out: malloc.c:2369: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) 
&((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && 
old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof 
(struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * 
(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & 
pagemask) == 0)' failed. 

중단됨 (코어 덤프)

나는 언어에 새로운 오전, 나는 매우 메모리 할당과 무료 방법의 개념을 이해하지 않습니다.

+0

'PFSEntry' 란 무엇입니까? 'PFSEntry.Filename'은 어떤 타입입니까? (그런데, 불행한 동화에 대해 듣고 유감스럽게 생각합니다.) –

+0

PFSEntry.Filename은 Char 파일명으로, – Andrew

+0

'Packed.HexEquivalent = DumpHex (FileNames [Counter]);는'HexEquivalent'가 바늘. 'DumpHex'는 메모리를 동적으로 할당합니까? 아니면 지역 변수에 대한 포인터를 반환하고 있습니까? 아니면 정적 버퍼로? 또는 ... 음, 어쩌면 당신은 그것을 보여 주어야합니다. 그리고 당신의 질문은 정확히 무엇입니까? "메모리 할당에 문제가 있습니까?"라는 것은 정확히 무엇을 의미합니까? –

답변

1

여기에 표시된 코드에서 오류가 발생하면 malloc의 자체 데이터 구조가 손상되어 어딘가에 배열 외부에 액세스 한 것처럼 보입니다.

일부 파일과 함께 작동한다는 것은 명백한 운명입니다. 그것은 정의되지 않은 동작의 문제입니다. 예기치 않은 동작이 정의되지 않은 동작의 한 형태 인 이유는 이러한 것을 추적하기가 어려운 버그입니다. 내가 여기서 무엇을 볼 수에서

, 이것은 잘못된 것입니다 :

while (Counter < FileSize) 
    { 
     Character = fgetc(File);  
     sprintf(HexArray + Counter, "%c", Character);  
     Counter++; 
    } 

HexArrayFileSize 바이트의 동적으로 할당 된 배열입니다. 그러나 sprintf()은 항상 출력 문자열을 null 바이트로 종료합니다.따라서 각 반복에 대해 은 Character으로 설정되고 HexArray[Counter+1]은 null 바이트로 설정됩니다. 마지막 반복을 제외하고는 아무런 해가 없습니다. CounterFileSize-1 (마지막 반복) 인 경우 sprintf()은 - 범위 외 범위에 null 바이트를 쓰게됩니다. 이는 정의되지 않은 동작이며 malloc 데이터 구조를 손상시킬 가능성이 높으므로 나중에 프로그램의 숨겨진 오류가 발생합니다.

당신이 원하는 모든 HexArray에 각 위치에 문자를 작성하는 경우, 당신은 훨씬 더 효율적이고 덜 오류가 발생하기 쉬운 형태로 사용할 수 있습니다 Characterunsigned char이기 때문에, 당신을 또한

while (Counter < FileSize) 
    { 
     Character = fgetc(File); 
     HexArray[Counter++] = Character; 
    } 

HexArraychar *에서 unsigned char *으로 변경해야합니다.

큰 파일의 경우 (프로그램이 해당 파일을 호출해야하는 경우)도 고려하십시오. 메모리 고갈은 현실입니다. 특히 임베디드 시스템 용으로 개발하는 경우에는 더욱 그렇습니다.

+0

대단히 감사합니다. 오류는 당신이 지적한 바로 그 곳이었습니다. 그래서 응용 프로그램은 모든 반복 된 파일에 대해 널 바이트로 스택을 겹쳐 쓰고 있었습니까? 그렇다면 왜 스택 스매싱 오류가 발생했는지 설명합니다. Filipe에게 다시 한번 감사드립니다. – Andrew

+0

@Andrew 기쁜 소식. 실제로, 매우 미묘한 버그! –