compare addresses - make sure one comes before the other

char str[] = "xz";
char * p1 = str;
char * p2 = str + 1;


Before I continue with another operation, I need to make sure that "p1 + 1" is positioned before another value in the same sequance. Im not used to comparing addresses, is this a valid way to check that?


if (p1 + 1 < p2)

Why not write yourself a small test program and try it? Trust me, you’ll learn a lot more about the dreaded pointer.
I tried it, it works. But maybe that's not all the facts. Always good to check with others as well
As long as both p1 + 1 and p2 point to the same array or one element past the end of the array then the comparison is valid. If this is not true, the behavior is undefined.
If possible, I would avoid these sorts of comparisons and restructure the code to deal with indices instead:
1
2
3
4
5
char str[] = "xz";
size_t i1 = 0;
size_t i2 = 1;

if (i1 + 1 < i2)
Last edited on
As long as both p1 + 1 and p2 point to the same array or one element past the end of the array then the comparison is valid.

How come the last + 1 is always valid. Seen that it is often used.
Is one extra automatically added to our sequence?

If possible, I would avoid these sorts of comparisons and restructure the code to deal with indices instead:

Because not by mistake comparing to an address outside the sequence?
Last edited on
How come the last + 1 is always valid. Seen that it is often used.
Because given T array[n];, you want to be able to compare pointers to (array + n) -- one element past the end. For example,
1
2
3
auto begin = array;
auto end = array + n;
for (auto i = begin; i < end; i++){ /*...*/ }

Is one extra automatically added to our sequence?
The details at that level aren't really important. They're for the compiler to deal with. The takeaway should be that you should be wary of code like
1
2
3
bool cmp(Foo *a, Foo *b){
    return a < b;
}
If you need to compare arbitrary pointers you should first convert them to uintptr_t or intptr_t.

Because not by mistake comparing to an address outside the sequence?
Yes. By using offsets you sidestep the issue entirely.
https://www.learncpp.com/cpp-tutorial/66-c-style-strings/
C-style strings

A C-style string is simply an array of characters that uses a null terminator. A null terminator is a special character (‘\0’, ascii code 0) used to indicate the end of the string. More generically, A C-style string is called a null-terminated string.

To define a C-style string, simply declare a char array and initialize it with a string literal:

1

char myString[]{ "string" };

Although “string” only has 6 letters, C++ automatically adds a null terminator to the end of the string for us (we don’t need to include it ourselves). Consequently, myString is actually an array of length 7!


If you need to compare arbitrary pointers you should first convert them to uintptr_t or intptr_t.

Can you give me a good example of this?

The details at that level aren't really important.

No, but they're interesting. And because we can compare an address in our array to an address that's outside the sequance (last + 1) Thats should mean that this is automatically added somehow, else it would be undefined behavior .
Last edited on
Can you give me a good example of this?
(uintptr_t)p1 < (uintptr_t)p2

And because we can compare an address in our array to an address that's outside the sequance (last + 1) Thats should mean that this is automatically added somehow
I don't know what you mean by "this" when you say "this is added". I have no idea what you're imagining in your head.
That's just what the language guarantees. In reality the implementation will have no choice (without expending additional effort that nobody would want) but to allow comparisons well past the end of an array. It depends on how the objects fall in memory and how the platform stores pointers. The standard is telling you that if you rely on pointer comparisons between unrelated objects your code may behave unpredictably.
1
2
3
char str[] = "xz";
char * p1 = str;
char * p2 = str + 1;

p1 points to str. p2 points to str+1. p1+1 points to str+1. So p1+1 == p2 right? Am I missing something?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

int main()
{
    char str[] = "xz";
    char * p1 = str;
    char * p2 = str + 1;
    
    std::cout << str << '\n';
    std::cout << p1 + 1 << '\n';
    std::cout << p2 << '\n';
    
    return 0;
}


Topic archived. No new replies allowed.