C、memset a double 数组失败

C, memset a double array failed

我想动态声明一个double类型的数组,所以这是我的代码

void function(int length, ...)
{
    ...

    double *a = malloc(sizeof(double) * length);
    memset(a, 1, sizeof(double) * length);
    for (int i = 0; i < length; i++)
    {
        printf("%f", a[i]);
    }

    ...
}

当我传递 2length 时,代码不会打印全 1。它只打印以下内容:

7.7486e-304
7.7486e-304

那么,我应该怎么做才能解决它?

memset 设置字节。您正在尝试设置双打。只需从 0 循环到 length 并将每个设置为 1.0:

for (int i = 0; i < length; i ++)
{
    a[i] = 1; // or 1.0 if you want to be explicit
}

memset 将数组的每个字节设置为 1 而不是每个 intdouble 元素。

您正在尝试设置 double 值(可能为 8 个或更多字节)。您的方法仅适用于数字 0.0,因为它恰好用所有字节表示 0 在使用 IEEE-754 浮点格式的系统上。请注意,这将是不可移植的,因为 C 标准允许浮点值的其他表示。

如果 a 指向整数数组,您的方法将适用于 0-1 以及一些特殊值,例如 0x01010101... 但是它仍然是一种不可移植的方法,因为它会失败,甚至会在具有填充位或非 2s 补码整数表示的奇异体系结构上调用未定义的行为。

初始化数组的正确方法是像这样的显式循环:

for (int i = 0; i < length; i++) {
    a[i] = 1.0;
}

编译器可能会将此循环编译成非常高效的代码。

您混淆了设置数组和设置存储数组的底层内存。

一个double由8个字节组成。您正在将构成双精度数的每个字节设置为 1。

如果你想将数组的每个元素初始化为 1.0,那么你可以使用 for(;;) 循环,或者因为你似乎在使用 C++,你可以使用容器并使用构造函数来初始化每个元素(如果构造函数有能力的话)或者用算法达到同样的效果。

memset一次设置1个字节。因此,我建议您使用自定义函数将任何数据类型的数组设置为有效值,如下所示:

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

void *g_memset(void *dst, void *val, size_t valSize, size_t count);

int main(void)
{
    double x = 1.0;
    double Array[50];
    g_memset(Array, &x, sizeof(x), 20);      /* set the 1st 20 elements to 1.0 */
    for (int n = 0; n < 20; n++) {
        printf("%.1lf ", Array[n]);
    }
    putchar('\n');
    return 0;
}

void *g_memset(void *dst, void *val, size_t valSize, size_t count)
{
    char *ptr = (char *)dst;
    while (count-- > 0) {
        memcpy(ptr, val, valSize);
        ptr += valSize;
    }
    return dst;
}

你使用memset来设置数组a的每个字节。双变量是8个字节,在memset数组a之后每个字节是1。 函数 memset 用于 char 数组。 如果你想初始化你的数组 a 你可以使用循环(while/for).

int j;
for(j =  0;i < length;j++)
    a[j] = 1;