Reputation:
I currently have I program I am writing where I am implementing a Mergesort of an array. The array is of unknown variables--it is a void pointer, so I don't actually know what sort of objects I'm sorting (there is a comparison function passed in for the actual comparisons).
How can I traverse the array when it is a void pointer? I've learned that I can't just use typical array format (i.e. arr[3]
) since it is a void pointer. There IS a parameter passed into my functions that holds the size of the mystery elements, so I suppose I would need that. Is there a way I could cast it depending on the provided size so I COULD use that typical array format, or do I have to use pointer arithmetic (again, having to somehow cast it to something of the provided size)?
Thanks to anyone who provides some input! :)
Upvotes: 4
Views: 627
Reputation: 726489
There IS a parameter passed into my functions that holds the size of the mystery elements
Good - that is precisely what you need to do the pointer arithmetic right. This is the same approach that qsort
library function is using.
void merge_sort(void *array, size_t N, size_t size, int (*compare)(const void *, const void *));
Once you cast the void*
pointer to a char*
, you would be able to compute the location of the mystery element i
as follows:
size_t size; // Element size
void *array; // The address of the array
size_t N; // Count of elements in the array
char *base = array;
for (int i = 0 ; i != N ; i++) {
void *elementAtPositionI = &base[i * size];
...
}
To find the point at which you split the array for sorting separately you can use the same technique:
void *secondHalf = &base[N * size / 2];
I can't quite get it to work though... it seems as if I'm skipping values and going into memory past the array!
A couple of major issues remain in your code:
num_elem/2
, when in fact one of them is num_elem/2+1
when num_elem
is odd. Use num_elem/2
for the left side and num_elem-num_elem/2
for the right side. Find all places where your assumption is made, and fix them (there's more than one place).merge(carr, carr + (num_elem/2) /* <<== HERE */, num_elem/2, num_elem/2, elem_size, cmp);
helper
incorrectly. Instead of helper[helper_place * elem_size] = *a_temp;
you need to call memcpy
and use elem_size
for the number of bytes to copy. There are several spots where you need to make this fix.This should bring you a lot closer to a working solution.
Upvotes: 2
Reputation: 206567
In mergesort
, you need to treat the pointers as char*
, You will need to pass the size of the objects so you would know how to perform pointer arithmetic correctly.
void mergesort(void* a, void* b, size_t objectSize, size_t objectCount)
{
char* ac = (char*)a;
char* bc = (char*)b;
//.....
mergesort(ac, ac+objectSize*objectCount/2);
}
Upvotes: 1