![]() |
memcmp() - compare buffer for 0
Hello,
#define MAX_LEN 6 unsigned char buf[MAX_LEN]; unsigned char zerobuf[MAX_LEN] = { 0 }; if (memcmp(buf, zerobuf, MAX_LEN) == 0) puts("buf is empty"); else puts("buf is not empty"); Is there another way to compare the input buffer for being equal to some pattern (all zeros in this case), i.e. ti avoid having additional array zerobuf? I think memcmp(buf, "0", MAX_LEN) isn't valid. Thanks. Mark |
Re: memcmp() - compare buffer for 0
On 2011-10-10, Mark <mark_cruzNOTFORSPAM@hotmail.com> wrote:
> Hello, > > #define MAX_LEN 6 > unsigned char buf[MAX_LEN]; > unsigned char zerobuf[MAX_LEN] = { 0 }; > > if (memcmp(buf, zerobuf, MAX_LEN) == 0) > puts("buf is empty"); > else > puts("buf is not empty"); > > Is there another way to compare the input buffer for being equal to some > pattern (all zeros in this case), i.e. ti avoid having additional array > zerobuf? I think memcmp(buf, "0", MAX_LEN) isn't valid. That's correct, memcmp(buf, "0", MAX_LEN) doesn't work. One reason it won't work is that the character '0' is not the same as a zero byte ('\0'). Another problem is that the array "0" has less than MAX_LEN elements so there's the danger of reading beyond the end of that array. One other way to do it, that does not use an additional array, is a simple linear search for the first nonzero element: size_t i = 0; while (i != MAX_LEN && buf[i] == 0) ++i; if (i == MAX_LEN) puts("all zeroes"); else puts("not all zeroes"); Yet another way is to sort the buf array in descending order and check whether buf[0] equals zero. If it does, the array contains only zeroes. There must be at least fifty other ways to do it. |
Re: memcmp() - compare buffer for 0
"Mark" <mark_cruzNOTFORSPAM@hotmail.com> writes:
> #define MAX_LEN 6 > unsigned char buf[MAX_LEN]; > unsigned char zerobuf[MAX_LEN] = { 0 }; > > if (memcmp(buf, zerobuf, MAX_LEN) == 0) > puts("buf is empty"); > else > puts("buf is not empty"); > > Is there another way to compare the input buffer for being equal to some > pattern (all zeros in this case), i.e. ti avoid having additional array > zerobuf? I think memcmp(buf, "0", MAX_LEN) isn't valid. If your compiler supports compound literals (a "new" feature in C99), you can do something like this: if (memcmp(buf, (char[MAX_LEN]){ 0 }, MAX_LEN) == 0) puts("buf is empty"); else puts("buf is not empty"); In the more general case -- well, it depends on just what the more general case turns out to be. This may be a specific example of a more general problem, but it's hard to tell what that more general problem is. (Note that an array is never really "empty". Your array is full; it just happens to be full of zeros.) -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
Re: memcmp() - compare buffer for 0
On 10/10/2011 5:38 PM, Mark wrote:
> Hello, > > #define MAX_LEN 6 > unsigned char buf[MAX_LEN]; > unsigned char zerobuf[MAX_LEN] = { 0 }; > > if (memcmp(buf, zerobuf, MAX_LEN) == 0) > puts("buf is empty"); > else > puts("buf is not empty"); > > Is there another way to compare the input buffer for being equal to some > pattern (all zeros in this case), i.e. ti avoid having additional array > zerobuf? I think memcmp(buf, "0", MAX_LEN) isn't valid. You think rightly, as others have explained. To use memcmp(), you'll need to compare to a region of memory as long as the test region, pre-initialized to the desired value. That's inescapable: it's how memcmp() operates. Alternatively, you could write a simple isAllZero() function that just looped through the test region comparing each byte to the desired value. That would surely use less data memory, but it's impossible to tell without measurement whether it would be faster or slower. The strspn() function might *almost* be made to work, if only you weren't looking for zeroes. As things stand, I see no way to employ it. -- Eric Sosman esosman@ieee-dot-org.invalid |
Re: memcmp() - compare buffer for 0
On 2011-10-10 14:38:59 -0700, Mark said:
> Is there another way to compare the input buffer for being equal to > some pattern (all zeros in this case), i.e. ti avoid having additional > array zerobuf? I'm surprised that no one offered the obvious answer that uses memcmp() without another array: if (MAX_LEN > 0 && buf[0] == 0 && memcmp(buf, buf + 1, MAX_LEN - 1) == 0) puts("buf is all zeros"); else puts("buf has at least one non-zero value"); Though it's probably faster to compare each entry to zero, or even faster to recast to an array of large integers and compare those to zero. Mark |
Re: memcmp() - compare buffer for 0
On 10/11/11 05:35 PM, Mark Adler wrote:
> On 2011-10-10 14:38:59 -0700, Mark said: >> Is there another way to compare the input buffer for being equal to >> some pattern (all zeros in this case), i.e. ti avoid having additional >> array zerobuf? > > I'm surprised that no one offered the obvious answer that uses memcmp() > without another array: > > if (MAX_LEN> 0&& buf[0] == 0&& memcmp(buf, buf + 1, MAX_LEN - 1) == 0) > puts("buf is all zeros"); > else > puts("buf has at least one non-zero value"); > > Though it's probably faster to compare each entry to zero, or even > faster to recast to an array of large integers and compare those to > zero. Usual alignment caveats apply! -- Ian Collins |
Re: memcmp() - compare buffer for 0
Eric Sosman <esosman@ieee-dot-org.invalid> writes:
> On 10/10/2011 5:38 PM, Mark wrote: >> Hello, >> >> #define MAX_LEN 6 >> unsigned char buf[MAX_LEN]; >> unsigned char zerobuf[MAX_LEN] = { 0 }; >> >> if (memcmp(buf, zerobuf, MAX_LEN) == 0) >> puts("buf is empty"); >> else >> puts("buf is not empty"); >> >> Is there another way to compare the input buffer for being equal to some >> pattern (all zeros in this case), i.e. ti avoid having additional array >> zerobuf? I think memcmp(buf, "0", MAX_LEN) isn't valid. > > You think rightly, as others have explained. > > To use memcmp(), you'll need to compare to a region of memory as > long as the test region, pre-initialized to the desired value. That's > inescapable: it's how memcmp() operates. There's a memcmp method that does not quite fit that description, though it is not likely to useful. In the same way that an object can be copied by successively doubling the copy region, so a region can be compared for all bytes the same by doubling the compare region (and it can be altered to handle longer patterns than all-bytes the same) assert(BUF_SZ != 0); size_t clen = 1; while (2*clen < BUF_SZ) if (memcmp(buf, buf + clen, clen) == 0) clen *= 2; else return false; return memcmp(buf, buf + clen, BUF_SZ - clen) == 0 && buf[0] == target; Rather like the previous suggestion to change a O(n) algorithm (a simple loop) into a O(n log(n)) one (sort and test buf[0]), this is no more than an exercise in possibilities. -- Ben. |
Re: memcmp() - compare buffer for 0
Ian Collins <ian-news@hotmail.com> writes:
> On 10/11/11 05:35 PM, Mark Adler wrote: >> On 2011-10-10 14:38:59 -0700, Mark said: >>> Is there another way to compare the input buffer for being equal to >>> some pattern (all zeros in this case), i.e. ti avoid having additional >>> array zerobuf? >> >> I'm surprised that no one offered the obvious answer that uses memcmp() >> without another array: >> >> if (MAX_LEN> 0&& buf[0] == 0&& memcmp(buf, buf + 1, MAX_LEN - 1) == 0) >> puts("buf is all zeros"); >> else >> puts("buf has at least one non-zero value"); >> >> Though it's probably faster to compare each entry to zero, or even >> faster to recast to an array of large integers and compare those to >> zero. > > Usual alignment caveats apply! Are there any in this case? -- Ben. |
Re: memcmp() - compare buffer for 0
On 10/11/11 10:11 PM, Ben Bacarisse wrote:
> Ian Collins<ian-news@hotmail.com> writes: > >> On 10/11/11 05:35 PM, Mark Adler wrote: >>> On 2011-10-10 14:38:59 -0700, Mark said: >>>> Is there another way to compare the input buffer for being equal to >>>> some pattern (all zeros in this case), i.e. ti avoid having additional >>>> array zerobuf? >>> >>> I'm surprised that no one offered the obvious answer that uses memcmp() >>> without another array: >>> >>> if (MAX_LEN> 0&& buf[0] == 0&& memcmp(buf, buf + 1, MAX_LEN - 1) == 0) >>> puts("buf is all zeros"); >>> else >>> puts("buf has at least one non-zero value"); >>> >>> Though it's probably faster to compare each entry to zero, or even >>> faster to recast to an array of large integers and compare those to >>> zero. >> >> Usual alignment caveats apply! > > Are there any in this case? What if the buffer is at an odd address? -- Ian Collins |
Re: memcmp() - compare buffer for 0
Ian Collins <ian-news@hotmail.com> writes:
> On 10/11/11 10:11 PM, Ben Bacarisse wrote: >> Ian Collins<ian-news@hotmail.com> writes: >> >>> On 10/11/11 05:35 PM, Mark Adler wrote: >>>> On 2011-10-10 14:38:59 -0700, Mark said: >>>>> Is there another way to compare the input buffer for being equal to >>>>> some pattern (all zeros in this case), i.e. ti avoid having additional >>>>> array zerobuf? >>>> >>>> I'm surprised that no one offered the obvious answer that uses memcmp() >>>> without another array: >>>> >>>> if (MAX_LEN> 0&& buf[0] == 0&& memcmp(buf, buf + 1, MAX_LEN - 1) == 0) >>>> puts("buf is all zeros"); >>>> else >>>> puts("buf has at least one non-zero value"); >>>> >>>> Though it's probably faster to compare each entry to zero, or even >>>> faster to recast to an array of large integers and compare those to >>>> zero. >>> >>> Usual alignment caveats apply! >> >> Are there any in this case? > > What if the buffer is at an odd address? Yes, I missed the last sentence right up to the point I hit send! Then I what what was being proposed (and you were commenting on). -- Ben. |
| All times are GMT. The time now is 12:46 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.