0

I have a dynamic array with this struct:

typedef struct vector_struct {
   size_t e_sz;
   char e_type;

   #define V_INT 1
   #define V_DOUBLE 2
   #define V_CHAR 3
   #define V_FLOAT 4


unsigned no_e;
unsigned cur_cap;
void* e_array;

}* vector_type;

where no_e is the size, cur_cap the capacity, e_sz is the size of the elements in the array and e_array is the void pointer.

I had to complete a push_back function that has to work for the 4 differetns types defined above.

void v_push_back(vector_type v, void* new_val){

if( v->no_e >= v->cur_cap ){

    /*** reallocate a larger array ***/
    v->cur_cap += (v->cur_cap) ? v->cur_cap : 2;

    v->e_array = realloc(v->e_array, v->cur_cap*(v->e_sz))

}
/*** copy new_val in the array at index v->no_e ***/

/*** TO BE DONE START ***/

if(v->e_type == 1)
    memcpy(((int*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);
else if(v->e_type == 2)
    memcpy(((double*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);
else if(v->e_type == 3)
    memcpy(((char*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);
else if(v->e_type == 4)
    memcpy(((float*)v->e_array) + v->no_e*(v->e_sz), new_val, v->e_sz);

/*** TO BE DONE END ***/

(v->no_e)++;
} 

This function works for the char, but it appears that it's not inserting either int or double. I can't find out the error in the code.

1 Answer 1

0

... + v->no_e*(v->e_sz) is wrong. You already cast to the appropriate type, so if you do + on an array of items, you get pointer arithmetic for that specific type. It is sufficient just to do ... + v->no_e because the item size is implicitly there based on the pointed-at type. This is why 1 byte chars work but nothing else.

Pointer arithmetic instead of array indexing is usually harder to read. I'd rewrite the code like this:

void* item;
switch(v->e_type)
{
   case V_INT:     item = &( (int*)    v->e_array )[v->no_e]; break;
   case V_DOUBLE:  item = &( (double*) v->e_array )[v->no_e]; break;
   case V_CHAR:    item = &( (char*)   v->e_array )[v->no_e]; break;
   case V_FLOAT:   item = &( (float*)  v->e_array )[v->no_e]; break;
}
memcpy(item, new_val, v->e_sz);

Note how a few spaces here and there turns repetitive code much more readable and minimizes the chance for typo-related bugs. Also note that this code is taking advantage of [] having higher operator precedence than &.

The pointer arithmetic alternative is actually pretty OK too in this specific case. Many might find this more readable:

void* item;
switch(v->e_type)
{
   case V_INT:     item = (int*)    v->e_array + v->no_e; break;
   case V_DOUBLE:  item = (double*) v->e_array + v->no_e; break;
   case V_CHAR:    item = (char*)   v->e_array + v->no_e; break;
   case V_FLOAT:   item = (float*)  v->e_array + v->no_e; break;
}
memcpy(item, new_val, v->e_sz);
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much I'll try your solution
I've tried but i have a different problem. The chars till works fine, but when i tried to print the array, instead of having a string of zeros in the ints i have random numbers.
Thank you for your time i have solved the problem. It was a paroblem in the print function

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.