C内存分配错误

时间:2014-02-24 20:25:17

标签: c runtime-error hexdump

您好我正在开发一个项目,我需要将文件打包到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 *)&amp;((av) - &gt; bins [((1) - 1)* 2])) - __builtin_offsetof(struct   malloc_chunk,fd))))&amp;&amp; old_size == 0)|| ((unsigned long)(old_size)

     
    

=(unsigned long)(((__ builtin_offsetof(struct malloc_chunk,fd_nextsize))+((2 *(sizeof(size_t))) - 1))&amp;〜((2 *(sizeof(size_t)))      - 1)))&amp;&amp; ((old_top) - &gt; size&amp; 0x1)&amp;&amp; ((unsigned long)old_end&amp; 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.

中止(核心倾销)

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

1 个答案:

答案 0 :(得分:1)

从这里显示的代码,并给出错误,看起来你有一个破坏malloc自己的数据结构的某个地方的数组访问。

它与某些文件一起工作的事实纯粹是运气,这是未定义行为的问题 - 表现得像预期的行为是一种未定义的行为,这就是使这些错误难以跟踪的原因。

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

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

HexArray是动态分配的FileSize字节数组。但请注意,sprintf()始终使用空字节终止输出字符串。因此,对于每次迭代,HexArray[Counter]设置为CharacterHexArray[Counter+1]设置为空字节。除了在最后一次迭代中,这没有任何害处。当CounterFileSize-1(最后一次迭代)时,sprintf()会将空字节写入HexArray[FileSize] - 超出范围的访问权限。这是未定义的行为,很可能会破坏malloc数据结构,从而在程序后期产生神秘错误。

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

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

另外,由于Characterunsigned char,您应该将HexArraychar *更改为unsigned char *

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