代码之家  ›  专栏  ›  技术社区  ›  Andrew

C内存分配错误

  •  0
  • Andrew  · 技术社区  · 12 年前

    嗨,我正在进行一个项目,需要将文件打包到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:Assertion`(old_top==((binptr)) ((char*)&((av)->bins[((1)-1)*2])-__builtin_offsetof(结构 malloc_cchunk(fd)))&&old_size==0)||((无符号长)(old_size)

    =(unsigned long)(((__builting_offsetof(struct malloc_cchunk,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.
    

    中止(堆芯转储)

    我对这门语言很陌生,我不太理解内存分配和自由方法的概念。

    1 回复  |  直到 12 年前
        1
  •  1
  •   Filipe Gonçalves    12 年前

    从这里显示的代码中,如果出现错误,看起来您有一个越界的数组访问正在损坏malloc自己的数据结构。

    它能处理某些文件是纯粹的运气,这就是未定义行为的问题-像预期那样的行为是一种未定义行为,这就是为什么像这样的bug很难跟踪的原因。

    从我这里看到的情况来看,这是错误的:

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

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

    如果您只想在 Hex阵列 ,您可以使用效率更高且不易出错的表单:

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

    此外,自 性格 unsigned char ,你应该改变 Hex阵列 从…起 char * unsigned char * .

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

    推荐文章