Reputation: 267
Heyo. In my C program, im dealing with lots of operations in which i have to read files, and store its data in arrays. For that, as the array handling in C is a little bit complicated, i'm using the following code suggested in this post:C dynamically growing array
typedef struct {
float *array;
size_t used;
size_t size;
} points;
void initArrayInd(arrayInd *a, size_t initialSize) {
a->array = (GLubyte *)malloc(initialSize * sizeof(GLubyte));
a->used = 0;
a->size = initialSize;
}
void insertArrayInd(arrayInd *a, GLubyte element) {
if (a->used == a->size) {
a->size *= 2;
a->array = (GLubyte *)realloc(a->array, a->size * sizeof(GLubyte));
}
a->array[a->used++] = element;
}
void freeArrayInd(arrayInd *a) {
free(a->array);
a->array = NULL;
a->used = a->size = 0;
}
I'm used to Java programming, so my way of thinking how should i code the things is, in most of the cases, wrong. I want to, based on this dynamic array allocation, be able to create a new function that will insert me a record in the position i have specified. I want to know what is the best way to do so.
Should i insert the the new record at the end of the array, and then shift everything one position. Should i create a new array, copy the i-1 elements, then place i and copy the i+n elements. Should i split the initial array into two, create a third and mix everything together. What is the best way in C to accomplish so?
EDIT: This would do it?
void insertFPointsAt(points *a, float element, int position) {
if (a->used == a->size) {
a->size *= 2;
a->array = (float *)realloc(a->array, a->size * sizeof(float));
}
memmove(&a->array[position], &a->array[position+1], &a->array[a->used] - &a->array[position]);
a->array[position] = element;
}
Upvotes: 4
Views: 4839
Reputation: 726609
When you insert in the middle of the array, you need to implement this algorithm:
memmove
The only step that's different from inserting at the end is the third one, where you move the content of your array up by one element. memmove
function deals with this correctly even when the two areas overlap.
EDIT: The memmove
call should look like this:
memmove(&a->array[position+1], &a->array[position], &a->array[a->used] - &a->array[position]);
A few additional notes:
malloc
is required, C does not require you to cast the return value of malloc
/calloc
/realloc
.Upvotes: 5
Reputation: 224964
You only ever need to shift the elements after the index you're trying to insert. Where you'll run into unnecessary copying is when you resize the array - the realloc
call might do a copy for you, and you'd end up copying twice. I'd do something like:
insert element E at index I:
if resize is necessary:
- allocate new larger buffer
- copy elements 0 to I-1 from old buffer into new buffer
- insert E at index I of new buffer
- copy elements I to end of old buffer into new buffer, starting at index I+1
- free old buffer
else
- copy elements I to end of buffer 'up by one' index
- insert E at index I of the buffer
Upvotes: 1