C、memset一个双数组失败
Posted
技术标签:
【中文标题】C、memset一个双数组失败【英文标题】:C, memset a double array failed 【发布时间】:2016-07-24 07:03:18 【问题描述】:我想动态声明一个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]);
...
当我传递2
的length
时,代码不会打印全1。它只打印以下内容:
7.7486e-304
7.7486e-304
那么,我该怎么做才能解决它?
【问题讨论】:
你为什么要标记这个c
?为什么在 C++ 代码中使用malloc
?
memset
设置字节。您正在尝试设置双打。只需从0
循环到length
并将每个设置为1.0
。
cout
不是c
!
cout
是标准模板库的一部分,因此是 C++。
既然您现在决定使用 C,您可以放弃 malloc
- ***.com/questions/605845/… 的演员表
【参考方案1】:
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.0
。【参考方案2】:
您混淆了设置数组和设置存储数组的底层内存。
double 由 8 个字节组成。您正在将构成双精度的每个字节设置为 1。
如果您想将数组的每个元素初始化为 1.0,那么您可以使用 for(;;) 循环,或者由于您确实使用 C++,您可以使用容器并使用构造函数来初始化每个元素(如果构造函数有能力)或使用算法达到同样的效果。
【讨论】:
谢谢,我知道我现在应该做什么来修复我的代码!double
不需要包含 8 个字节。它可以是 9、10 甚至 1(考虑到目标上的一个字节具有 >=64 位)。并且 OP 使用 C,而不是 C++
没错,没有要求有 8 个字节,但大多数都需要,并且在原始帖子中@AlexanderYau 在他的代码中有cout
。自从发布我的答案后,他就回去编辑了。【参考方案3】:
memset
将数组的每个字节设置为 1
而不是每个 int
或 double
元素。
您正在尝试设置 double
值(可能是 8 个或更多字节。)您的方法仅适用于数字 0.0
,因为它恰好在使用 IEEE-754 的系统上用所有字节 0
表示浮点格式。请注意,这将是不可移植的,因为 C 标准允许浮点值的其他表示形式。
如果a
指向一个整数数组,您的方法将适用于0
和-1
以及一些特殊值,例如0x01010101
... 但它仍然是一种不可移植的方法,因为它在具有填充位或非 2s 补码整数表示的奇异架构上会失败甚至调用未定义的行为。
初始化数组的正确方法是这样的显式循环:
for (int i = 0; i < length; i++)
a[i] = 1.0;
编译器可能会将这个循环编译成非常高效的代码。
【讨论】:
-1 适用于整数类型,但不适用于浮点。 IEEE-745 浮点数是符号-指数-尾数; 1.0 和 -1.0 之间的唯一区别是符号位。设置所有位的值是 NaN。 @rici:-1
仅适用于 2s 补码整数和使用的所有位。对于 1s 或 s/m,它也会失败。【参考方案4】:
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;
【讨论】:
【参考方案5】:您使用memset
设置数组a
的每个字节。双变量为8 个字节,在memset
数组a
之后每个字节为1。
函数memset
用于char
数组。
如果你想初始化你的数组a
,你可以使用循环(while/for)。
int j;
for(j = 0;i < length;j++)
a[j] = 1;
【讨论】:
以上是关于C、memset一个双数组失败的主要内容,如果未能解决你的问题,请参考以下文章