as a beginner in C, I am struggling with an obscure problem and because I couldn't find a solution to this particular problem I want to ask you the following: Currently I am trying to understand void pointers and their arithmetic operations. I attempted to write a generic function, which accepts a void pointer to an array, the length of the array and size of one element and splits the given array into two different parts (list1 and list2):
void split(void *array, int arrlen, int objsize)
{
// divide the arrlen and save the values
int len_list1 = arrlen / 2;
int len_list2 = arrlen - len_list1;
// Allocate memory for two temporary lists
void *list1 = (void*)malloc(objsize * len_list1);
void *list2 = (void*)malloc(objsize * len_list2);
if (list1 == NULL || list2 == NULL)
{
printf("[ERROR]!\n");
exit(-1);
}
// list1 gets initialized properly with int and char elements
memmove(list1, array, len_list1*objsize);
printf("list1:");
print_arr(list1, len_list1);
// memmove((char*)list2, (char*)array+list_1_length, list_2_length*objsize); (*)
memmove(list2, (int*)array+len_list1, len_list2*objsize);
printf("list2:");
print_arr(list2, len_list2);
}
My problem is the following: If I give this function an int array it will work fine, but if I call split() with a char array as an argument, I have to...
memmove((char*)list2, (char*)array+list_1_length, list_2_length*objsize);
//memmove((int*)list2, (char*)array+list_1_length, list_2_length*objsize);
comment line (*) out, in order to have the same results. A solution certainly could be to write an if-else condition and test the objsize:
if (objsize == sizeof(int))
// move memory as in the 1st code snippet
else
// move memory with the (int*) cast
But with this solution I would also have to check other data types, so it would be very kind of you to give me a hint.
Thanks!
-matzui
memmove(list2, (int*)array+len_list1, len_list2*objsize);
Here you typecast array
to an int *
, and add len_list1
to it. But adding something to a pointer, means it will be multiplied with the size of one element of the datatype of that pointer. So if an int is 4 bytes, and you add 5 to an int *
variable, it will move 20 bytes.
Because you know exactly how many bytes you want to move the pointer, you can cast is to char *
(char = 1 byte), and add the number of bytes to it.
So instead of (int*)array+len_list1
, you can use (char*)array+(len_list1*objsize)