0

您好我正在做一个项目,我需要将文件打包到 PFS 映像中。我正在使用 ANSI C 语言编写应用程序。我正在获取每个文件 Hexdump 和其他属性并存储在变量中。

一旦收集了有关正在打包的文件的所有信息,我需要创建一个包含每个文件信息的输出文件。

当我这样做时,我在内存分配方面遇到了麻烦。输出错误的代码如下。

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:2369: sysmalloc: 断言`(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)' 失败。中止(核心转储)

以下是添加到应用程序中的一些调试信息,可能有助于找到解决方案。

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.

中止(核心转储)

我是该语言的新手,我不太了解内存分配的概念和免费方法。

4

1 回答 1

1

从这里显示的代码,并给出错误,看起来您在某处有一个超出范围的数组访问,这破坏了 malloc 自己的数据结构。

它适用于某些文件的事实是纯粹的运气,这就是未定义行为的问题 - 像预期的那样行为是一种未定义行为的形式,这就是使此类错误难以跟踪的原因。

从我在这里看到的,这是错误的:

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

HexArrayFileSize是一个动态分配的字节数组。但是,请注意sprintf()始终以空字节结束输出字符串。因此,对于每次迭代,HexArray[Counter]设置为Character,并且HexArray[Counter+1]设置为空字节。除了最后一次迭代之外,这并没有什么坏处。当CounterFileSize-1(最后一次迭代)时,sprintf()会将一个空字节写入HexArray[FileSize]-越界访问。这是未定义的行为,很可能会破坏 malloc 数据结构,从而在程序后期产生神秘错误。

如果您只想在 中的每个位置写入一个字符HexArray,则可以使用更高效且不易出错的形式:

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

此外,由于Characteris unsigned char,您应该HexArray从更改char *unsigned char *

还要考虑大文件会发生什么(如果你的程序应该被这些文件调用)。内存耗尽是一个现实,特别是如果您正在为嵌入式系统开发(似乎就是这种情况)。

于 2014-02-24T21:55:33.950 回答