我最近在C中研究了 malloc(),声明如下:
void *malloc(size_t size)
其中size_t
是unsigned int,size
定义no。要保留的字节数。
问题是我的系统 float 值占用了4个字节的内存。所以,如果我使用2bytes的malloc制作内存指针(浮点型),
float *p;
p = (float *)malloc(2);
那么为什么它不会给出任何错误?因为我认为浮点数据需要4个字节所以如果我只发出2个字节,那么它可能会导致一些数据丢失。
还是我不正确理解malloc()?
答案 0 :(得分:2)
在您给出的示例中,如果您只为float *
分配2个字节,然后通过取消引用指针尝试写入该位置,那么您将写入不具有&t; t的内存被分配了。这导致undefined behavior。这意味着它可能有效,可能是核心转储,或者它可能以不可预测的方式运行。
如果要为一个或多个浮点数分配内存,可以这样做:
// allocates space for an array of 5 floats
// don't cast the result of malloc
int arrayLen = 5;
float *f = malloc(sizeof(float) * arrayLen);
答案 1 :(得分:1)
如果您尝试使用该指针,这可能会有问题 - 实际上指针很好,它指向的分配内存太小了 - 编译器没有这样做的原因认识到它是错误的事实是指针不是"意识到"它指向的是,实际上指针是包含内存地址的变量,所以基本上它们只是一个数字,并且在大多数情况下(如user694733指出的那样)指针的大小是相同的,无论它指向一个短的或浮动。 编译器看到的是从(void *)到(float *)的转换,对于编译器来说,它是一个完全有效的转换。
答案 2 :(得分:1)
您遇到了C Standard
要求的特定于实现的结果7.22.3内存管理功能
连续调用分配的存储顺序和连续性
calloc
,malloc
,realloc
和malloc()
函数 没有具体说明。 如果分配成功,则返回指针 适当地对齐,以便可以将其分配给指向任何类型的指针 具有基本对齐要求的对象然后习惯 在空间中访问这样的对象或这样的对象的数组 已分配(直到空间被明确解除分配)。
为了提供“适当对齐的存储,以便可以将其分配给指向具有基本对齐要求的任何类型对象的指针”,实现必须从malloc()
等返回内存< / em>在特定偏移量处,是系统最严格的对齐要求的倍数。这通常是8或16字节。
鉴于返回的每个块必须以这种方式对齐,大多数实现在内部创建内存块,这是对齐要求的倍数。
因此,如果您的系统具有8字节对齐要求,即使您请求了两个字节,您的{{1}}实现也可能实际上为您提供8字节的内存块。同样地,要求19个字节,你可能会在现实中获得24个字节。
但是,超出你所要求的范围仍然是未定义的行为。不幸的是,未定义的行为包括“工作正常”。
答案 3 :(得分:0)
你的问题实际上与malloc无关,而是与数据转换无关。在这种情况下,您已经将从malloc返回的地址开始的字节转换为float。因此,如果您稍后说*p = 0.0f;
,您实际上会将4个字节写入上述内存区域,但由于您只分配了2个字节,因此只有2个字节可供您使用。因此,您的代码将在内存损坏的情况下编译和运行(这将导致崩溃,或者在以后出现意外的运行时行为)