比较 void * 是否包含 0 个字节?

comparing if void * contains 0 numbytes?

我需要通用方法来检查 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;
    }

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

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

您可以将指针转换为 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;

我可能会选择这样的东西:

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

注意:对于对齐良好的长缓冲区,此方法可能更好。然而 由于简单而快速。

由于内存,如果全为零,必须与自身进行比较,使用 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) 次迭代。

接受答案后的另一个:

由于内存,如果全为零,必须与自身进行比较,使用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;
}