简体   繁体   English

C内存分配错误

[英]C Memory Allocation Error

Hi I am working on a project, where I need to Pack files into a PFS Image. 嗨,我正在一个项目中,我需要将文件打包到PFS映像中。 I am writing an application using the ANSI C language. 我正在使用ANSI C语言编写应用程序。 I am getting each files Hexdump and other attributes and storing inside variables. 我正在获取每个文件的十六进制转储和其他属性,并存储在变量内部。

Once all Information about the Files being packed is gathered, I need to create an output file with each file's infromation. 收集了有关要打包的文件的所有信息后,我需要使用每个文件的信息创建一个输出文件。

As I am doing this, I am having trouble with memory allocation. 在执行此操作时,我在分配内存时遇到了麻烦。 The Code outputting the error is as follows. 输出错误的代码如下。

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;


}

The structure which the loop above fills is shown below 上面的循环填充的结构如下所示

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

and the DumpHex Function is as follows: 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;
}

The Function DumpHex, which returns the hex output of the given file is outputting the following error. 返回给定文件的十六进制输出的函数DumpHex输出以下错误。

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) || 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) ((无符号长)(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. =(无符号长)((((((__ 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)'失败。 Aborted (core dumped) 中止(核心已弃用)

Below are some Debug information added to the application that may help in the finding solution. 以下是一些添加到应用程序中的调试信息,这些信息可能有助于查找解决方案。

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.

Aborted (core dumped) 中止(核心已弃用)

I am new to the language, and I don't quite understand the concept of memory allocation and the free method. 我是该语言的新手,并且我不太了解内存分配和自由方法的概念。

From the code shown here, and given the error, it looks like you have an out of bounds array access somewhere that is corrupting malloc's own data structures. 根据此处显示的代码,并给出错误信息,您似乎在超出范围的数组访问中破坏了malloc自己的数据结构。

The fact that it works with some files is sheer luck, that's the problem with undefined behaviour - behaving like expected is a form of undefined behaviour, this is what makes bugs like these hard to track. 它可以与某些文件一起工作的事实真是运气,这就是未定义行为的问题-像预期的那样,行为是未定义行为的一种形式,这使得难以跟踪此类错误。

From what I can see here, this is wrong: 从这里我可以看到,这是错误的:

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

HexArray is a dynamically allocated array of FileSize bytes. HexArrayFileSize字节的动态分配数组。 However, note that sprintf() always terminates the output string with a null-byte. 但是,请注意, sprintf()始终以空字节终止输出字符串。 Thus, for each iteration, HexArray[Counter] is set to Character , and HexArray[Counter+1] is set to a null byte. 因此,对于每次迭代,将HexArray[Counter]设置为Character ,并将HexArray[Counter+1]设置为一个空字节。 There's no harm in this except in the last iteration. 除了最后一次迭代,此操作没有任何害处。 When Counter is FileSize-1 (the last iteration), sprintf() will be writing a null byte into HexArray[FileSize] - out of bounds access . CounterFileSize-1 (最后一次迭代)时, sprintf()将向HexArray[FileSize]写入一个空字节- 超出范围 This is undefined behaviour and will most likely corrupt malloc data structures, thus yielding the cryptic errors later in the program. 这是未定义的行为,很可能会破坏malloc数据结构,从而在程序后面产生神秘错误。

If all you want to do is to write a character to each position in HexArray , you can use the much more efficient and less error-prone form: 如果您要做的就是在HexArray每个位置写入一个字符,则可以使用效率更高,更不易出错的形式:

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

Also, since Character is unsigned char , you should change HexArray from char * to unsigned char * . 另外,由于Characterunsigned char ,因此您应该将HexArraychar *更改为unsigned char *

Consider also what happens with huge files (if your program is supposed to be invoked with those). 还请考虑大型文件会发生什么(如果应该使用这些文件来调用您的程序)。 Memory exhaustion is a reality, especially if you're developing for an embedded system (which seems to be the case). 内存耗尽是现实,特别是如果您正在为嵌入式系统开发(事实就是如此)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM