c,memset双数组失败

时间:2016-07-24 07:03:18

标签: c memset

我想动态声明一个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]);
    }

    ...
}

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

7.7486e-304
7.7486e-304

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

5 个答案:

答案 0 :(得分:8)

memset设置字节。你正试图设置双打。只需从0循环到length,然后将每个设置为1.0

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

答案 1 :(得分:3)

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;
}

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

答案 2 :(得分:3)

您在设置数组和设置存储数组的基础内存时感到困惑。

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

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

答案 3 :(得分:1)

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;
}

答案 4 :(得分:-1)

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

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