1

我正在实现一个简单的merge函数,但我被卡住了,因为编译器给了我无法解释的错误。这是我的merge功能:

void merge(void *a, int beg, int middle, int end, int (*cmp)(const void*, const void*
{
  std::stack<void*> first;
  std::stack<void*> second;

  for(int i = beg; i < middle; i++) {
   first.push(a+i);
  }
  for(int i = middle; i < end; i++) {
    second.push(a+i);
  }

  for(int i = beg; i < end; i++) {
    if(first.empty()) {
      void *tmp = second.top();
      second.pop();
      a+i = tmp;
    } else if(second.empty()) {
      void *tmp = first.top();
      first.pop();
      a+i = tmp;
    } else if(cmp(first.top(), second.top())) {
      void *tmp = first.top();
      first.pop();
      a+i = tmp;
    } else {
      void *tmp = second.top();
      second.pop();
      a+i = tmp;
    }
  }
}

这是错误:

sort.h: In function `void merge(void*, int, int, int, int (*)(const void*, const void*))':
sort.h:9: error: pointer of type `void *' used in arithmetic
sort.h:12: error: pointer of type `void *' used in arithmetic
sort.h:19: error: pointer of type `void *' used in arithmetic
sort.h:19: error: non-lvalue in assignment
sort.h:23: error: pointer of type `void *' used in arithmetic
sort.h:23: error: non-lvalue in assignment
sort.h:27: error: pointer of type `void *' used in arithmetic
sort.h:27: error: non-lvalue in assignment
sort.h:31: error: pointer of type `void *' used in arithmetic
sort.h:31: error: non-lvalue in assignment

谁能帮我?TIA。

4

5 回答 5

4

指针算术是不可能的void*,因为void它没有大小,并且指针算术需要根据类型的大小来计算内存地址。

如果您期望beg,middleend来表示字节偏移量,您应该使用char指针来代替(一个char是一个字节)。

如果您想编写一个适用于任何类型的通用函数,请不要使用void指针而是模板:

template <typename t>
void merge(T *a, int beg, int middle, int end, int (*cmp)(const T*, const T*))
{
    // ...
}
于 2012-06-28T15:14:25.757 回答
1

first.push(a+i);中,您正试图向指针添加i偏移void *a。这是非法的。

您可以将偏移量添加到任何其他“某物指针”,因为该物将被定义并且将在内存中具有定义的大小。sizeof(something)因此,添加 1 的偏移量将意味着在内存中向前移动。但void没有定义的大小。因此,您不能将偏移量与void *指针一起使用。

于 2012-06-28T15:14:14.960 回答
1

问题void*在于它是一个没有类型的地址。当你要求a+i你说“i进一步移动元素”时,没有指定什么样的元素。是一个字节,一个整数,一辆车,一栋房子,还是一个大陆?

In C++ you don't have to use this kind of stuff, you can use templates and let the compiler figure out how to handle different types.

template<class T>
void merge(T* a, etc.
于 2012-06-28T15:18:38.173 回答
1

Function prototype probably should look something like this:

void merge(void **a, int beg, int middle, int end, int (*cmp)(const void*, const void*));

Then you can access every array member by its index without any problem.

Note: The size of object pointed by void is unknown as previously mentioned by Ferdinand (therefore a + i can't be applied), but the size of void* is known therefore updating prototype in a such way does the trick.

于 2012-06-28T15:20:29.957 回答
0

我可以告诉你你的一个错误。您正在尝试对 a 进行指针运算void*。您会看到,当您添加到指针时,您添加的是指针类型中的字节数。因此,如果您添加到 a void*,编译器无法知道要添加多少字节,因为void*没有类型。因此,如果您想在字节级别执行此操作,请转换为 achar*或您想要的任何其他指针级别。如果你想一个字节一个字节地做事,你可以取 a void*,但转换成char*.

于 2012-06-28T15:15:48.013 回答