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