David G
David G

Reputation: 96810

Offset from a memory address

I was reading some code and I came across this example. What I don't understand is why the author uses an offset of 1 from both variables on the last line. At first glance I would assume this is illegal because it is referring to a possibly uninitialized memory area (and it could cause a segmentation fault). My head keeps telling me undefined behavior but is this really so?

static bool lt(wchar_t a, wchar_t b)
{
    const std::collate<wchar_t>& coll =
        std::use_facet< std::collate<wchar_t> >(std::locale());
    return coll.compare(&a, &a+1, &b, &b+1) < 0;
}

The last line is the one in question. Why is it necessary that he's doing this, is it legal, and when should it be done?

Upvotes: 3

Views: 723

Answers (3)

ubi
ubi

Reputation: 4399

Testing your function

#include <locale>

static bool lt(wchar_t a, wchar_t b)
{
    const std::collate<wchar_t>& coll =
        std::use_facet< std::collate<wchar_t> >(std::locale());
    return coll.compare(&a, &a+1, &b, &b+1) < 0;
}


int main () {

    bool b = lt('a', 'b');
    return 0;
}

Inside the debugger

Breakpoint 1, main () at test.cpp:13
13      bool b = lt('a', 'b');
(gdb) s
lt (a=97 L'a', b=98 L'b') at test.cpp:6
6           std::use_facet< std::collate<wchar_t> >(std::locale());
(gdb) p &a
$1 = 0x7fffffffdddc L"a\001翿\x400885"
(gdb) p &a+1
$2 = 0x7fffffffdde0 L"\001翿\x400885"

From this I believe

  1. the code is legal
  2. but &a + 1 is referring to possibly uninitialized memory

From what gdb returns I tend to think taking the address of a wchar_t returns a char* thus &a (a is a wchar_t) is a char* to the start of the multibyte variable that is a and &a+1 returns pointer to the second byte. Am I correct?

Upvotes: 0

aah134
aah134

Reputation: 860

what book are you reading, plus it depends on what are you comparing too!

sometimes you need to compare an ID that happens to be in the beginning of buffer, and with a certain size.

Upvotes: 0

user530189
user530189

Reputation:

It appears that the author just wanted to compare two characters using the current global locale.

Since std::collate<T>::compare uses [low, high) for the two ranges, adding 1 to the address of the parameters will simply cause the comparison to stop after only a is compared to b. There should be no invalid memory accesses.

Upvotes: 1

Related Questions