如何合并声明为void指针的两个数组?

时间:2014-05-02 03:23:37

标签: void-pointers

我目前有程序我正在编写我正在实现数组的Mergesort。数组是未知变量 - 它是一个无效指针,所以我实际上并不知道我排序的对象类型(实际比较中传递了比较函数)。

当它是一个void指针时,如何遍历数组?我已经知道我不能只使用典型的数组格式(即arr[3]),因为它是一个无效指针。有一个参数传递到我的函数中,它保存了神秘元素的大小,所以我想我需要它。有没有一种方法可以根据提供的大小来构建它,所以我可以使用那种典型的数组格式,或者我是否必须使用指针算法(再次,不得不以某种方式将其转换为提供的大小)?

感谢任何提供一些意见的人! :)

2 个答案:

答案 0 :(得分:2)

  

我的函数中传递了一个参数,它包含了神秘元素的大小

好 - 这正是你需要做正确的指针运算。这与qsort库函数正在使用的方法相同。

void merge_sort(void *array, size_t N, size_t size, int (*compare)(const void *, const void *));

void*指针强制转换为char*后,您就可以按如下方式计算神秘元素i的位置:

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];
    ...
}

要找到分割数组以便单独排序的点,可以使用相同的技术:

void *secondHalf = &base[N * size / 2];
  

我无法让它工作......但好像我正在跳过数值并进入数组内存!

您的代码中仍存在一些主要问题:

  • 您的代码会跳过值,因为您错误地计算了左侧和右侧部分的大小:您认为它们都是num_elem/2,而实际上其中一个num_elem/2+1num_elem是奇怪的。左侧使用num_elem/2,右侧使用num_elem-num_elem/2。找到您所做假设的所有地方,并修复它们(不止一个地方)。
  • 您的代码进入了错误的内存,因为您错误地计算了中间位置。您需要对此行进行修复:merge(carr, carr + (num_elem/2) /* <<== HERE */, num_elem/2, num_elem/2, elem_size, cmp);
  • 您正在将元素复制到helper中。您需要调用helper[helper_place * elem_size] = *a_temp;而不是memcpy而不是elem_size来复制要复制的字节数。您需要在几个位置进行此修复。

这可以让您更接近工作解决方案。

答案 1 :(得分:1)

mergesort中,您需要将指针视为char*,您需要传递对象的大小,以便您知道如何正确执行指针算法。

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);
}