Why is my bool pointer comparison function always returning TRUE?

Aug 11, 2017 at 9:01am
As the title says. I'm trying compare two int arrays using pointers, with the code below. It _does_ return a value but the value is always 0, and I'm not quite sure why.

The way I understand it, the 'while' loop in my function should break as soon as *a[x] and *b[x] don't match, which in this case should be immediately. But obviously I understand it wrong, because that's not what's happening.

I don't want anyone to write the code for me, but if someone could please explain where my logic is faulty I would really appreciate it.

Cheers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <cstdlib>
#include <iostream>

using namespace std;

bool check(int* a, int* b);

int main(int argc, char** argv) {

    int a[] = {1,2,3,4,5};
    int b[] = {5,4,3,3,1};
    int *p = a;
    int *q = b;
    
    cout << check(p,q) << endl;
    cout << a[0] <<  " " << b[0] << endl;
    
    return 0;
}

bool check(int* a, int* b){
    
    while(*a++ == *b++);
    
    return *a == *b;
}
Last edited on Aug 11, 2017 at 9:02am
Aug 11, 2017 at 9:09am
because that's not what's happening.

Indeed it is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

bool check(int* a, int* b);

int main(int argc, char** argv) {

    int a[] = {1,2,3,4,5};
    int b[] = {5,4,3,3,1};
    int *p = a;
    int *q = b;
    
    std::cout << check(p,q) << '\n';
    std::cout << a[0] <<  " " << b[0] << '\n';
    
    return 0;
}

bool check(int* a, int* b){
    
    while(*a++ == *b++) {
        std::cout << "If you can read this sentence, it means there's a match "
                     "with the arrays.\n";
    }
    return *a == *b;
}

Aug 11, 2017 at 9:16am
So is it my return line that's faulty?
Aug 11, 2017 at 9:17am
It _does_ return a value but the value is always 0, and I'm not quite sure why

In this case, ‘zero’ means ‘false’. I you want to read ‘true’ or ‘false’, you need to use the ‘boolalpha’ manipulator.
Since you don't want code, I'm just giving you a reference:
http://en.cppreference.com/w/cpp/io/manip/boolalpha
Aug 11, 2017 at 9:17am
It compares 1 and 5 ... so it will stop "while"ing immediately.

However, it will complete the while bracket first, so pointers a and b WILL have incremented and will now be pointing to the next elements in the arrays.
So, the final comparison is
return 2 == 4 (NOT 1 == 5)
This is false, so 0.


If you change your second array to
int b[] = {5,2,3,3,1};
the second element comparison will be
return 2 == 2
which returns true, or 1.


EDIT: I'm a slow writer: there were 3 replies in the time it took me to type that!
Last edited on Aug 11, 2017 at 9:19am
Aug 11, 2017 at 9:18am
It _does_ return a value but the value is always 0, and I'm not quite sure why.

Because a boolean false value is represented as the integer zero.
1
2
	cout << boolalpha;
	cout << check(p,q) << endl;

false



By the way the code is flawed since the check function has no idea of the length of either array.
This will also (probably?) report as false
1
2
	int a[] = {1,2,3,4,5};
	int b[] = {1,2,3,4,5};

Why? because this loop while(*a++ == *b++); doesn't stop until it finds two values which are not the same - even if it is in some area of memory outside the bounds of the arrays. But bear in mind the pointers are incremented after testing, so the actual result is not certain.

On the other hand, this reports as true:
1
2
	int a[] = {1,2,7,4,5};
	int b[] = {1,2,-6,4,5};

It stops when the pair 7, -6 are compared. But then the pointers a and b are each incremented and now point to 4, 4 which are equal.

Last edited on Aug 11, 2017 at 9:21am
Aug 11, 2017 at 9:20am
lastchance -> that doesn't seem to work, when I change the arrays to be identical it still returns 0. If I return *--a == *--b it still returns 0. It's ALWAYS 0.

EDIT: Chervil thanks for the addition. So how would I go about comparing pointers then, if I'm not certain of their size, since there is no .length() function?
Last edited on Aug 11, 2017 at 9:25am
Aug 11, 2017 at 9:23am
If you make the arrays identical then you will END UP POINTING BEYOND THE END OF THEM.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <cstdlib>
#include <iostream>

using namespace std;

bool check(int* a, int* b);

int main(int argc, char** argv) {

    int a[] = {1,2,3,4,5};
    int b[] = {5,2,3,3,1};          // CHANGED HERE
    int *p = a;
    int *q = b;
    
    cout << check(p,q) << endl;
    cout << a[0] <<  " " << b[0] << endl;
    
    return 0;
}

bool check(int* a, int* b){
    
    while(*a++ == *b++);
    
    return *a == *b;
}



Here's the output from C++ shell - TRY IT! See the little 1 (true) in the first line below.
1
1 5



If you want the number of elements then use, e.g.,
sizeof(a)/sizeof(int)
Last edited on Aug 11, 2017 at 9:29am
Aug 11, 2017 at 9:28am
lastchance -> hmm yours does return a 1. I think I must be a bit thick or something, leave this with me to puzzle over.
Aug 11, 2017 at 9:29am
Hi,

It returns false because 2 != 4 Despite the body of the loop not executing, a and b are still incremented.

The return statement is dangerous: if the the 2 arrays are equal, a and b are incremented out range, so possibly 2 pieces of garbage are being compared. The same could be said about the while condition, it will keep going through memory it doesn't own until it finds something unequal. See below about NULL termination.

Btw, if you are going to have an intentional null statement, document it, and always uses braces:

1
2
3
4
while(*a++ == *b++) {
    ;  // null statement
    
}


It looks like you are trying to adapt a C strcpy function, but that relies on having NULL terminated char array, the same is not going to work for a compare function. The C strcmp function also relies on NULL termination.

I would write something that involved the sizes of the arrays.

Edit: Lots of replies while doing mine, at least we are all saying the same things !

Btw the C strcpy function looks like this:

1
2
3
4
5
void strcpy (char* a, char* b) {
  while(*a++ = *b++) { // assignment not equality 
    ;  // null statement  
  }
}


I just included that for completeness, not to be used for this problem.
Last edited on Aug 11, 2017 at 9:36am
Aug 11, 2017 at 9:45am
The C strcmp function looks like this:

1
2
3
4
5
6
7
/* strcmp: return <0 if s < t, 0 if s==t, >0 if s >t */ 
int strcmp(char* s, char* t) {
   for ( ; *s == *t; s++, t++) {
      if (*s == '\0') {return 0;}
   }
   return *s - *t;
}
Last edited on Aug 11, 2017 at 9:45am
Aug 11, 2017 at 10:02am
Try this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <cstdlib>
#include <iostream>
using namespace std;

bool check( int* a, int* b, int n );

int main()
{
   int a[] = {1,2,3,4,5};
// int b[] = {1,2,3,4,5,6};            // try the different variants
// int b[] = {1,2,3,4,5};
   int b[] = {5,4,3,2,1};

   // Length check
   int na = sizeof( a )/ sizeof( a[0] );
   int nb = sizeof( b )/ sizeof( b[0] );
   if ( na != nb )
   {
      cout << "The arrays are unequal length\n";
      return 0;
   }

   int *p = a;
   int *q = b;
   cout << "Arrays are equal? " << boolalpha << check( p, q, na ) << endl;
}

bool check( int* a, int* b, int n )
{
   while( n > 0 && *a == *b ) { n--;  a++;   b++; }
// while( n && *a++ == *b++ ) n--;        // shorter, but very obscure
   return ( n == 0 );                 
}
Topic archived. No new replies allowed.