使用零有效地附加大数组?

时间:2012-11-01 20:50:12

标签: c

我有一个名为A的数组,其中包含随机浮点数,其大小在[10000,1000000]的范围内。这个数组是我的函数随机生成的参数,为了对它进行操作,我试图以高效的方式抢先/填充10000个零。我担心附加A的已分配内存会破坏堆,所以我将新内存中的新内存,memcopy A和memset 10000尾随浮点数分配给0.0。

void *ArrayPadder(float *A){
    int pad = 10000;
    float *Apadded = (float*)malloc((sizeof(A)+pad)*sizeof(float));
    memcpy(Apadded, A, sizeof(A));
    memset(Apadded+sizeof(A), 0.0, pad);
    return Apadded;
}

有人能建议更有效的方法来实现这个目标吗?

编辑:对延迟表示歉意,但我补充了一些说明。我不能只预先分配正确的内存空间(510000浮点数)的原因是因为数组实际上是随机大小,包含随机浮点数。我选择500000试图简化问题,现在已经修复了。

4 个答案:

答案 0 :(得分:6)

不是更有效的方式,而是更准确的方式:

memset(Apadded+sizeof(A), 0, pad * sizeof(float));

好像浮点数的大小为4,您的代码只会初始化第一个pad / sizeof(float) = 10000 / 4 = 2500 elements

请注意,我使用0而不是0.0作为第二个参数,因为memset接受一个int并将其(低字节)值设置为所有字节。

答案 1 :(得分:3)

  

我正在尝试有效地附加/填充10000个零

追加和填充不一定是一回事。我假设您希望通过10,000个元素增加现有的内存块。

为什么不预先分配正确的尺寸并完成它呢?

#define BASE_SIZE 500000
#define PAD_SIZE  10000

/* ... */

float *data = malloc((BASE_SIZE + PAD_SIZE) * sizeof(float));
if(!data) {
    /* do something */
}

memset(data + BASE_SIZE, 0, PAD_SIZE * sizeof(float));
/* last PAD_SIZE elements are now 0 */

另请注意,memset需要设置 bytes 的数量,而不是元素,所以这样:

memset(Apadded+sizeof(A), 0.0, pad);

错了。应该是pad * sizeof(float)pad是元素的数量,sizeof(float)给出每个元素的字节数。

答案 2 :(得分:2)

这取决于A的定义方式。如果它在堆上分配,只需使用realloc()

Apadded = realloc(A, new_size);

答案 3 :(得分:0)

乔丹,您的代码存在一些问题。您没有显示A的定义方式,但您在sizeof(A)调用中对malloc的使用必定是错误的。要分配扩展内存,您需要malloccallocreallocrealloc只能在A指向堆上分配的内存区域(例如,通过malloc)的情况下使用。

float *Apadded = realloc(A, (number_of_entries_in_A + pad) * sizeof(float));

realloc会将A的内容复制到Apadded,但会使填充区域保持未初始化状态。请注意,realloc可能会失败,在这种情况下A仍然存在,之后必须被释放。

如果A是静态分配的,那么您需要malloccalloccalloc会将内存初始化为零,但由于你要将A复制到Apapped,这很浪费。所以malloc最好。

float *Apadded = malloc((number_of_entries_in_A + pad) * sizeof(float));

请注意,number_of_entries_in_Asizeof(A)不同。另请注意,C中没有强制转换。

要初始化填充区域,您可以将memsetsizeof(A)一起使用。但请注意,如果A是一个指针,那么这将失败,因为sizeof(A)将只是指针的大小,而不是数组。

memcpy(Apadded, A, sizeof(A));
memset(Apadded+sizeof(A), 0, pad);

另请注意,尽管可能如此,但可能无法保证浮点0.0由全零表示。