我对C很陌生,所以请忍受我的无能。我想将整个EXEcutable文件读入缓冲区:
#include <stdlib.h>
FILE *file = fopen(argv[1], "rb");
long lSize;
fseek(file, 0, SEEK_END);
lSize = ftell(file);
fseek(file, 0, SEEK_SET);
char *buffer = (char*) malloc(sizeof(char)*lSize);
fread(buffer, 1, lSize, file);
该文件有6144个字节(在lSize中正确存储),但我的缓冲区大小只有4个字节,因此只有MZ签名存储在缓冲区中。
为什么malloc在这种情况下只分配4个字节?
修改 可能char缓冲区由PE文件的MZ头中的前0个终止。但是,如果我将缓冲区设置为某个值,则将存储整个文件。如果我将缓冲区设置为int(= 4字节),缓冲区将不会被终止,但当然会更大(相对于char = 1字节)。我只是想用空字节复制文件字节的字节。
编辑2: 缓冲区当然包含应有的一切,但如果我尝试用fwrite将其写入一个新文件,它只会写入第一个\ 0(即4个字节)。我刚搞错了。修正了这一点对不起,问题还不够明确。
答案 0 :(得分:7)
如果lSize
确实等于6144
,那么您的代码将确实分配6144
个字节,然后读取文件的全部内容。如果您认为只读取了4个字节,则可能是因为第5个字节为零。因此,当缓冲区被解释为零终止字符串时,它将在该点终止。
您可以通过查看buffer[4]
,buffer[5]
等来检查缓冲区的其余部分。
另外,根据定义,您无需从malloc
和sizeof(char) == 1
转换回报。最佳做法是像这样写malloc
:
char *buffer = malloc(lSize);
但这不会改变你的结果。
答案 1 :(得分:3)
为什么malloc在这种情况下只分配4个字节?
因为您未能#include <stdlib.h>
(并转换malloc()
的返回值)。
不要忘记#include <stdlib.h>
,以便编译器知道malloc
返回类型void*
的值(而不是假设它返回int
})并采用size_t
类型的参数(而不是假设它是int
)
也不要转换malloc
的返回值。可以将类型void*
的值分配给指针(对任何类型)类型的对象。转换返回值会使编译器以静默方式将int
(假设未包含<stdlib.h>
时)转换为强制转换中的类型。请注意,编译器会在没有演员表的情况下抱怨让您知道您忘记了包含。
真正的错误不是malloc
分配错误的金额(我相信它会分配正确的金额)。 真正的错误是假设malloc在返回void *时返回一个int。 int
和void*
可以不同的方式传递(一个在寄存器中,另一个在堆栈中实例)或者它们有不同的表示形式(int
的两个补码和void*
的分段地址)或任何其他东西(最有可能是sizeof (int) != sizeof (void*)
)。
答案 2 :(得分:1)
你是如何检查缓冲区的大小的,你在做sizeof(buffer)
吗?在这种情况下,您只能看到pointer to int
的大小为4个字节。你无法从它的指针中获得缓冲区的大小。您必须单独存储(在lSize
中)。
如果malloc()
没有返回NULL
,那么你的缓冲区很好,大小正确。