Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiently appending a large array with zeros?

Tags:

c

I have an array named A that contains random floats, with its size anywhere in the range from [10000, 1000000]. This array is a randomly generated argument to my function, and in order to operate on it I am trying to preemptively append/pad it with 10000 zeros in an efficient manner. I am worried that appending A's allocated memory will corrupt the heap, so instead I allocate new memory, memcopy A, and memset 10000 trailing floats in the new Array to 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;
}

Can anyone suggest a more efficient way of accomplishing this?

EDIT: Apologies for the delay but I added some clarification. The reason I can't just pre-allocate the correct memory space (510000 floats) is because the array is actually of random size, containing random floats. I chose 500000 in an attempt to simplify the question, which is now fixed.

like image 248
Jordan Smith Avatar asked Nov 01 '12 20:11

Jordan Smith


3 Answers

Not really a more efficient way, but a more accurate way:

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

as if the size of float is 4, your code only initializes the first pad / sizeof(float) = 10000 / 4 = 2500 elements

Note that I used 0 and not 0.0 as the second parameter, as memset takes an int and sets its (low byte) value to all of the bytes.

like image 153
MByD Avatar answered Nov 05 '22 16:11

MByD


I am trying to efficiently append/pad it with 10000 zeros

Appending and padding are not necessarily the same thing. I assume you want to grow an existing chunk of memory by 10,000 elements.

Why don't you just allocate the correct size up front and be done with it?

#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 */

Also note that memset takes the number of bytes to set, not elements, so this:

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

Is wrong. Should be pad * sizeof(float). pad is the number of elements, sizeof(float) gives the number of bytes per element.

like image 31
Ed S. Avatar answered Nov 05 '22 14:11

Ed S.


This depends how A is defined. If it's allocated on the heap, just use realloc():

Apadded = realloc(A, new_size);
like image 39
Olaf Dietsche Avatar answered Nov 05 '22 16:11

Olaf Dietsche