比较if void *是否包含0 numbytes?

时间:2015-09-17 18:13:56

标签: c void-pointers

我需要通用的方法来检查void *是否包含0到num_bytes。 我提出了以下方法。 * p每次都不包含相同类型的数据,因此无法*(type*)p

bool is_pointer_0(void *p, int num) {                
    void *cmp;
    cmp = (void*)malloc(num);
    memset(cmp, 0, num);
    if (memcmp(p, cmp, num)) {
        free(cmp);
        return false;
    } else {
        free(cmp);
        return true;
    }        
}

该功能分配&每次调用时释放num个字节,我认为不是很好。 请建议更快的方法。感谢帮助。

更新:

这种做法怎么样?

   bool is_pointer_0(void *p, int num) {
        void *a = NULL;
        memcpy(&a, p, num);

        return a == NULL;
    }

5 个答案:

答案 0 :(得分:8)

此代码将void指针强制转换为char指针。这允许指向的内存被视为一个字节序列。然后循环指定的长度,寻找非零字节。我不知道标准是否保证这会起作用(即向char *转换void *将提供指向原始字节的指针),但在现实生活中它可以工作

bool is_pointer_0(void *p, int num) {                
    char *c = (char *)p;
    for(int i = 0; i < num; i++)
         if(c[i]) return false;
    return true;
}

答案 1 :(得分:4)

您可以将指针转换为char*unsigned char*并检查元素的值。

unsigned char* cp = reinterpret_cast<unsigned char*>(p);
for (int i = 0; i < num; ++i )
{
   if ( cp[i] != 0 )
   {
      return false;
   }
}
return true;

答案 2 :(得分:1)

注意:这种方法对于良好对齐的长缓冲区可能更好。但由于简单,this answer很快。

由于内存(如果全部为零)必须与自身进行比较,请使用memcmp():特定于平台的优化函数。

int memcmp0(const void *buf, size_t n) {
  #define TESTVALUE 0
  const char *cbuf = (const char *) buf;
  while (n > 0) {

    // If odd size, last byte not 0?
    if (n % 2 && (cbuf[n - 1] != TESTVALUE)) return 0;

    // 1st half matches 2nd half?
    size_t half = n / 2;
    if(memcmp(cbuf, &cbuf[half], half) != 0) return 0;

    n = half;
  }
  return 1;
}

通过更改0,可以轻松扩展到TESTVALUE以外的其他值。

注意:最多log2(n)次迭代。

答案 3 :(得分:0)

接受回答后的另一个:

由于内存(如果全部为零)必须与自身进行比较,请使用memcmp():特定于平台的优化函数。

检查第一个值,然后使用memcmp()比较ptr[0],ptr[1],然后ptr[1],ptr[2],然后ptr[2],ptr[3]等。

int memcmpfast(const void *ptr, size_t n, char testvalue) {
  const char *cptr = (const char *) ptr;
  if (n == 0) return 1;
  if (cptr[0] != testvalue) return 0;
  return memcmp(cptr, cptr + 1, n - 1) == 0;
}

答案 4 :(得分:-1)

我可能会选择这样的事情:

bool is_pointer_0(void* p, int num)
{
    return std::search_n((char*)p, (char*)p + num, num, 0) == p;
}

或者这个:

bool is_pointer_0(void* p, int num)
{
    return std::all_of((char*)p, (char*)p + num, [](char c){return c == 0;});
}