使用malloc()时数据大小的兼容性

时间:2016-01-13 13:12:56

标签: c pointers memory-management malloc

我最近在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()?

4 个答案:

答案 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内存管理功能

     

连续调用分配的存储顺序和连续性   callocmallocreallocmalloc()函数   没有具体说明。 如果分配成功,则返回指针   适当地对齐,以便可以将其分配给指向任何类型的指针   具有基本对齐要求的对象然后习惯   在空间中访问这样的对象或这样的对象的数组   已分配(直到空间被明确解除分配)。

为了提供“适当对齐的存储,以便可以将其分配给指向具有基本对齐要求的任何类型对象的指针”,实现必须从malloc() 等返回内存< / em>在特定偏移量处,是系统最严格的对齐要求的倍数。这通常是8或16字节。

鉴于返回的每个块必须以这种方式对齐,大多数实现在内部创建内存块,这是对齐要求的倍数。

因此,如果您的系统具有8字节对齐要求,即使您请求了两个字节,您的{{1}}实现也可能实际上为您提供8字节的内存块。同样地,要求19个字节,你可能会在现实中获得24个字节。

但是,超出你所要求的范围仍然是未定义的行为。不幸的是,未定义的行为包括“工作正常”。

答案 3 :(得分:0)

你的问题实际上与malloc无关,而是与数据转换无关。在这种情况下,您已经将从malloc返回的地址开始的字节转换为float。因此,如果您稍后说*p = 0.0f;,您实际上会将4个字节写入上述内存区域,但由于您只分配了2个字节,因此只有2个字节可供您使用。因此,您的代码将在内存损坏的情况下编译和运行(这将导致崩溃,或者在以后出现意外的运行时行为)