繁体   English   中英

memset 对浮点数组做了什么?

[英]What is memset doing to a float array?

我最近在网上找到了一段代码,看起来有点像这样:

#include <stdio.h>
#include <string.h>

int main() {
    float m[10];
    memset(m, 0, 20); 
}

我还看到了一个片段,我认为它是正确的:

memset(m, 0, sizeof m); 

尝试使用此代码段打印出第一个示例的所有值时:

for (int i = 0; i < 20; i++) {
    printf("%f, \n", m[i]);
}

它产生一个 output 像这样:

0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
-0.000000, 
-4587372491414098149376.000000, 
-0.000013, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000

重新编译时值发生变化的地方。

现在我有几个问题:

  • 为什么 memset 可以比分配的更多写入float -array,为什么不能使用char -array 执行此操作?
  • 为什么如此不一致?
  • 为什么将第二个值更改为memset的值例如1不会更改 output?

为什么 memset 可以比分配的更多写入float -array,为什么不能使用char -array 执行此操作?

memset(m, 0, 20); ,正如问题最初显示的那样,写入的内容不超过分配的内容。 通常, float在 C 实现中是四个字节,所以float m[10]; 分配 40 个字节和memset(m, 0, 20); 写 20。

在新代码中, memset(m, 0, sizeof m); m写入尽可能多的字节,不多也不少。

如果要求memset写更多,您可以尝试这样做的原因是 C 实现通常不进行安全检查操作,而 C 标准不要求它们这样做。

为什么如此不一致?

没有什么不一致的。 memset将零写入m的前 20 个字节,这是浮点零的编码,采用float常用的格式(IEEE-754 binary32,也称为“单精度”)。

之后的字节没有被写入,因此打印它们使用未初始化的数据。 C 标准说未初始化对象的值是不确定的。 一个常见的结果是程序已经使用了 memory 中的任何内容。 那可能是零,也可能是其他东西。

但是, for (int i = 0; i < 20; i++)的循环,您 go 超出了m中的 10 个元素。 那么访问m[i]的行为不是由 C 标准定义的。 如上所述,一个常见的结果是程序访问计算的 memory 并使用发生的任何内容。 但是,其他各种行为也是可能的,包括由于尝试访问未映射的 memory 或编译器在优化期间用替代代码替换未定义代码而导致的崩溃。

为什么更改memset的第二个值不会更改 output?

它将取决于您将其更改为什么。 字节的某些值可能会导致float值非常小,它们仍然打印为“0.000000”。 例如,如果将字节设置为 1,使每个float中的 32 位0x01010101 ,它们表示float2.36942782761723955384693006253917004604239556833255136345174597127722672385008451101850084511018181850084511018181818

如果您使用 64 作为memset的第二个参数,则这些位将设置为0x40404040 ,它对值 3.0039215087890625 进行编码,因此将打印“3.003922”。

Memsetfloat组没有任何作用。 您只有一个包含 10 个浮点数的数组,并且您使用了一个覆盖 20 个浮点数的循环,这意味着,由于 C 不检查数组边界……您已经从数组的末尾扩展了很远,并将其解释为浮点数不是。 我不会在这里重复其他答案中已经说过的内容,但是您在调整 C 对象的大小时遇到了问题。 sizeof运算符是您的朋友。 在将 arguments 传递给memcpymalloc等函数时使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM