C语言 C 缓冲区内存分配

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7777524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:54:37  来源:igfitidea点击:

C buffer memory allocation

cmalloc

提问by Laughingman

I'm quite new to C so please bear with my incompetence. I want to read an whole EXEcutable file into a buffer:

我对 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);

The file has 6144 bytes (stored correctly in lSize) but the size of my buffer is only 4 bytes, therefore only the MZ signature is stored in the buffer.

该文件有 6144 字节(正确存储在 lSize 中),但我的缓冲区的大小仅为 4 字节,因此缓冲区中仅存储 MZ 签名。

Why does malloc only allocate 4 bytes in this case?

为什么 malloc 在这种情况下只分配 4 个字节?

Edit:Probably the char buffer is terminated by the first 0 in the MZ header of the PE file. If I set the buffer to a certain value however, the whole file will be stored. If I set the buffer to int (= 4 bytes), the buffer won't be terminated but will be of course larger (vs. char = 1 byte). I just want to copy the file byte for byte with the null bytes as well.

编辑:可能字符缓冲区由 PE 文件的 MZ 标头中的第一个 0 终止。但是,如果我将缓冲区设置为某个值,则将存储整个文件。如果我将缓冲区设置为 int(= 4 字节),则缓冲区不会终止,但当然会更大(与 char = 1 字节相比)。我只想用空字节复制文件字节。

Edit 2:The buffer of course contains everything it should but if I try to write it to a new file with fwrite, it only wrote up to the first \0 (which is 4 bytes). I just got fwrite wrong. Fixed this. Sorry, the problem wasn't well defined enough.

编辑 2:缓冲区当然包含它应该包含的所有内容,但是如果我尝试使用 fwrite 将其写入新文件,它只会写入第一个 \0(即 4 个字节)。我刚刚写错了。修复了这个。抱歉,问题定义不够明确。

回答by David Heffernan

If lSizereally does equal 6144then your code will indeed allocate 6144bytes and then read the entire contents of the file. If you believe that only 4 bytes are being read it is probably because the 5th byte is a zero. Thus when buffer is interpreted as a zero terminated string, it terminates at that point.

如果lSize确实相等,6144那么您的代码确实会分配6144字节,然后读取文件的全部内容。如果您认为只有 4 个字节被读取,那可能是因为第 5 个字节是零。因此,当缓冲区被解释为零终止字符串时,它会在该点终止。

You can inspect the rest of your buffer by looking at buffer[4], buffer[5], etc.

您可以通过查看检查你的缓冲区的其余部分buffer[4]buffer[5]等。

As an aside, you don't need to cast the return from malloc, and sizeof(char) == 1by definition. Best practice is to write the malloclike this:

顺便说一句,根据定义,您不需要从malloc, 转换返回sizeof(char) == 1。最佳实践是这样写malloc

char *buffer = malloc(lSize);

But that will not change your results.

但这不会改变你的结果。

回答by pmg

Why does malloc only allocate 4 bytes in this case?

为什么 malloc 在这种情况下只分配 4 个字节?

Because you failed to #include <stdlib.h>(and cast the return value of malloc()).

因为您未能#include <stdlib.h>(并转换 的返回值malloc())。



Do not forget to #include <stdlib.h>so that the compiler knows mallocreturns a value of type void*(rather than assuming it returns an int) and takes an argument of size_ttype (rather than asuuming it is an int)

不要忘记#include <stdlib.h>让编译器知道malloc返回一个类型的值void*(而不是假设它返回 an int)并接受一个size_t类型的参数(而不是假设它是 an int

Also do not cast the return value of malloc. A value of type void*can be assigned to an object of pointer (to any type) type. Casting the return value makes the compiler silently convert int(assumed when <stdlib.h>was not included) to the type in the cast. Note the compiler would complain without the cast letting you know you had forgotten the include.

也不要强制转换malloc. void*可以将类型值分配给指针(指向任何类型)类型的对象。强制转换返回值会使编译器默默地转换int(假定<stdlib.h>未包含时)为转换中的类型。请注意,编译器会在没有演员让您知道您忘记了包含的情况下抱怨。



The real error is not mallocallocating the wrong amount (I believe it will allocate the correct amount anyway). The real error is assuming malloc returns an int when it returns a void*.intand void*can be passed differently (one in a register, the other on the stack for instance) or they have different representations (two's complement for intand segmented address for void*) or any other thing (most probably sizeof (int) != sizeof (void*)).

真正的错误不是malloc分配错误的金额(我相信无论如何它都会分配正确的金额)。真正的错误是假设 malloc 在返回 void* 时返回 int。int并且void*可以以不同的方式传递(例如一个在寄存器中,另一个在堆栈中)或者它们具有不同的表示形式(二进制补码int和分段地址void*)或任何其他东西(最有可能sizeof (int) != sizeof (void*))。

回答by RedX

how are you checking for the size of buffer, are you doing a sizeof(buffer)? In that case you are only seeing the size of a pointer to intwhich is 4 bytes. You cannot get the size of a buffer out of it's pointer. You must store it separately as you have done (in lSize).

你如何检查缓冲区的大小,你在做什么sizeof(buffer)?在这种情况下,您只能看到 a 的大小,pointer to int即 4 个字节。您无法从指针中获取缓冲区的大小。您必须像您所做的那样将其单独存储(在 中lSize)。

If malloc()did not return NULLthen your buffer is fine and the size is correct.

如果malloc()没有返回,NULL那么您的缓冲区很好并且大小正确。