嗨,我正在做一个项目,在那里我需要将文件打包到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) x((无符号长) (old_size) ) =(__builtin_offsetof (struct malloc_chunk,fd_nextsize))+((2 *(sizeof(Size_t))- 1))和~(2*(sizeof(Size_t))-1)和((old_top)->size & 0x1)和((未签名长)old_end& pagemask) == 0)‘failed。中止(核心倾弃)
下面是添加到应用程序中的一些调试信息,这些信息可能有助于查找解决方案。
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.中止(核心倾弃)
我对这门语言很陌生,我也不太明白内存分配和自由方法的概念。
发布于 2014-02-24 21:55:33
从这里显示的代码来看,考虑到错误,您似乎可以访问某个范围外的数组,从而破坏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数据结构,从而导致程序后面的神秘错误。
如果您只想在HexArray中的每个位置写入一个字符,那么您可以使用更高效、更容易出错的形式:
while (Counter < FileSize)
{
Character = fgetc(File);
HexArray[Counter++] = Character;
}另外,由于Character是unsigned char,所以您应该将HexArray从char *更改为unsigned char *。
还可以考虑如何处理大型文件(如果您的程序应该与这些文件一起调用)。内存耗尽是一个现实,特别是当您正在为嵌入式系统开发时(情况似乎是这样)。
https://stackoverflow.com/questions/21998247
复制相似问题