Mar*_*ers 20
但是,如果您确实想要检查内存区域是否全为零,则可以将其与自身进行比较,但是将其移动一个.
bool allZero = pMem[0] == '\0' && !memcmp(pMem, pMem + 1, length - 1);
Run Code Online (Sandbox Code Playgroud)
其中length是您想要为零的字节数.
Ste*_*sop 14
由于马克的回答引起了一些争议:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifndef count
#define count 1000*1000
#endif
#ifndef blocksize
#define blocksize 1024
#endif
int checkzeros(char *first, char *last) {
for (; first < last; ++first) {
if (*first != 0) return 0;
}
return 1;
}
int main() {
int i;
int zeros = 0;
#ifdef EMPTY
/* empty test loop */
for (i = 0; i < count; ++i) {
char *p = malloc(blocksize);
if (*p == 0) ++zeros;
free(p);
}
#endif
#ifdef LOOP
/* simple check */
for (i = 0; i < count; ++i) {
char *p = malloc(blocksize);
if (checkzeros(p, p + blocksize)) ++zeros;
free(p);
}
#endif
#ifdef MEMCMP
/* memcmp check */
for (i = 0; i < count; ++i) {
char *p = malloc(blocksize);
if (*p == 0 && !memcmp(p, p + 1, blocksize - 1)) ++zeros;
free(p);
}
#endif
printf("%d\n", zeros);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果(cygwin,Windows XP,Core 2 Duo T7700在2.4 GHz):
$ gcc-4 cmploop.c -o cmploop -pedantic -Wall -O2 -DEMPTY && time ./cmploop
1000000
real 0m0.500s
user 0m0.405s
sys 0m0.000s
$ gcc-4 cmploop.c -o cmploop -pedantic -Wall -O2 -DLOOP && time ./cmploop
1000000
real 0m1.203s
user 0m1.233s
sys 0m0.000s
$ gcc-4 cmploop.c -o cmploop -pedantic -Wall -O2 -DMEMCMP && time ./cmploop
1000000
real 0m2.859s
user 0m2.874s
sys 0m0.015s
Run Code Online (Sandbox Code Playgroud)
因此,对于我来说,memcmp大约需要(2.8 - 0.4)/(1.2 - 0.4)= 3倍.看到其他人的结果很有意思 - 我的所有malloced内存都归零,所以我总是得到每次比较的最坏情况时间.
对于较小的块(以及更多的块),比较时间不太重要,但memcmp仍然较慢:
$ gcc-4 cmploop.c -o cmploop -pedantic -Wall -O2 -DEMPTY -Dblocksize=20 -Dcount=10000000 && time ./cmploop
10000000
real 0m3.969s
user 0m3.780s
sys 0m0.030s
$ gcc-4 cmploop.c -o cmploop -pedantic -Wall -O2 -DLOOP -Dblocksize=20 -Dcount=10000000 && time ./cmploop
10000000
real 0m4.062s
user 0m3.968s
sys 0m0.015s
$ gcc-4 cmploop.c -o cmploop -pedantic -Wall -O2 -DMEMCMP -Dblocksize=20 -Dcount=10000000 && time ./cmploop
10000000
real 0m4.391s
user 0m4.296s
sys 0m0.015s
Run Code Online (Sandbox Code Playgroud)
我对此感到有些惊讶.我期望memcmp至少能够竞争,因为我希望它能够内联并针对编译时已知的小尺寸进行优化.即使更改它以便它在开始时测试一个int然后再测试16个字节的memcmp,以避免未对齐的最坏情况,也不会加快它的速度.
如果你正在测试它,然后只在它为0时才使用它,那么请注意你有一个竞争条件,因为@Mark Byers建议的方法没有原子测试/设置操作.在这种情况下,很难让逻辑正确.
如果你想将它归零,如果它还不是零,那么只需将其设置为零,因为它会更快.
C++解决方案:
bool all_zeroes =
(find_if( pMem, pMem+len, bind2nd(greater<unsigned char>(), 0)) == (pMem+len));
Run Code Online (Sandbox Code Playgroud)
如您所述,memcmp将一块内存与另一块内存进行比较.如果你已经知道的另一块内存全部为零,那么你可以使用该参考块与候选块进行比较,看它们是否匹配.
听起来你没有另一块记忆.你只有一个,你想知道它是否全部为零.标准库不提供这样的功能,但是编写自己的函数很容易:
bool is_all_zero(char const* mem, size_t size)
{
while (size-- > 0)
if (*mem++)
return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
如果你想分配一个新的内存块并立即将其全部归零,那么请使用calloc而不是malloc.如果您要将内存块设置为全零,则使用memset或std::fill.
| 归档时间: |
|
| 查看次数: |
2028 次 |
| 最近记录: |