我有一些数组,
float *large_float_array;
我是calloc并在循环后尝试memset
large_float_array = (float*)calloc(NUM, sizeof(float));
// .. do stuff with float array
memset(large_float_array, 0, sizeof(large_float_array);
// .. do other stuff
但似乎large_float_array
实际上并未归零。为什么是这样?这是由于浮点数的特殊属性吗?如果是这样,我想知道如何解决这个问题。
P.S。 calloc
实际上也在这里工作吗?
答案 0 :(得分:5)
你不能使用memset,因为它接受int
作为值类型,但float可能以不同的方式存储,所以你应该使用常规循环
size_t i
for(i = 0; i < NUM; ++i){
large_float_array[i] = 0.;
}
答案 1 :(得分:3)
calloc
初始化内存区域并使用memset
函数实现0
值的效果实际上是相同的。换句话说,calloc
不再是memset
的“类型”。它们都只是将所有位设置为内存*。
C11(N1570)7.22.3.2/2 calloc函数:
calloc
函数为nmemb对象数组分配空间, 每个尺寸都是大小。空间初始化为所有位零。 296)
脚注296(仅供参考):
请注意,这不一定与表示相同 浮点零或空指针常量。
*)可以想象calloc
可以返回已经使用零预先初始化的内存位置的地址,因此它可能比malloc + memset
组合更快。
答案 2 :(得分:3)
由于large_float_array
是指针,因此不能使用sizeof(large_float_array)
指定要清除的字节数。你必须写:
memset(large_float_array, 0, NUM * sizeof(float));
请注意,C标准并未严格指定将所有位设置为零,因为将所有值设置为0.0
。但在大多数当前架构中,它将按预期工作。
清除阵列的正确方法是:
#include <stdlib.h>
...
for (size_t i = 0; i < NUM; i++) {
large_float_array[i] = 0;
}
答案 3 :(得分:1)
发布有多个问题。
以下没有均衡()
。不清楚OP的真实代码是什么。
memset(large_float_array, 0, sizeof(large_float_array);
假设上面的简单使用了另一个)
,那么代码只用零填充几个字节为零,因为sizeof(large_float_array)
是指针的大小。
memset(large_float_array, 0, sizeof(large_float_array));
OP可能想要一些零填充已分配空间的零位。这将使分配的内存处于与calloc()
相同的状态。
memset(large_float_array, 0, NUM *sizeof *large_float_array);
代码应该使用以下内容。一个好的编译器会将这个简单的循环优化为快速代码。
for (size_t i=0; i<NUM; i++) {
large_float_array[i] = 0.0f;
}
使用快速memcpy()
的一种方法是将float
复制到数组的第一个元素,然后将第一个元素复制到第二个元素,然后将前两个元素复制到元素3&amp; 4,然后前4个元素到元素4,5,6,7 ...
void *memset_size(void *dest, size_t n, const char *src, size_t element) {
if (n > 0 && element > 0) {
memcpy(dest, src, element); // Copy first element
n *= element;
while (n > element) {
size_t remaining = n - element;
size_t n_this_time = remaining > element ? element : remaining;
memcpy((char*)dest + element, dest, n_this_time);
element += n_this_time;
}
}
return dest;
}
float pi = M_PI;
float a[10000];
memset_size(a, 10000, &pi, sizeof pi);
与所有优化一样,首先考虑清楚编写的代码,然后在有选择的案例中使用上述候选人。