Why is my bool pointer comparison function always returning TRUE?

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

So is it my return line that's faulty?
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
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
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
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
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
lastchance -> hmm yours does return a 1. I think I must be a bit thick or something, leave this with me to puzzle over.
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
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
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.