0

Imagine these:

int main (void)
{
    int V[101];
    populateSomehow(V);
    std::sort(V, &V[100]); //which one
    std::sort(V, V+100);
}

Is there a 'safer one'?

Lucas Steffen
  • 1,244
  • 2
  • 10
  • 22
  • 2
    Both miss the 101st element. Really, just use `std::end` unless you actually meant for the first 100 to be sorted. – chris Sep 17 '14 at 03:23
  • They are identically equivalent. I prefer the first but opinions no doubt vary. – user207421 Sep 17 '14 at 03:24
  • 1
    @EJP The first is good for this case but the same pattern doesn't work if you want to actually sort the whole array – M.M Sep 17 '14 at 03:28
  • @MattMcNabb Please explain. – user207421 Sep 17 '14 at 03:29
  • 1
    @EJP, You can read through the horrific discussion [here](http://stackoverflow.com/questions/988158/take-the-address-of-a-one-past-the-end-array-element-via-subscript-legal-by-the). C actually says that `&arr[i]` is equivalent to `arr + i`, whereas C++ doesn't, so that possible dereferencing of `arr + i` is what causes problems. – chris Sep 17 '14 at 03:32
  • @MattMcNab Thanks, but I can't see any consensus there on a quick scan. – user207421 Sep 17 '14 at 03:34
  • 1
    @EJP There seems to be no consensus, which would be a good reason to avoid it, especially considering there's a simple well-defined alternative. – M.M Sep 17 '14 at 03:41
  • @MattMcNabb You forget I'm a compiler writer, I can't leave it at that. The answers there that claim it is UB refer to accesses beyond the end of the array. This one isn't. – user207421 Sep 17 '14 at 03:43
  • @EJP I didn't know you were a compiler writer in the first place, so I couldn't forget it. :) Further discussion of this should happen on that thread rather than in comments here – M.M Sep 17 '14 at 03:45
  • 1
    @EJP, That's precisely what Matt meant by it not working if sorting the whole array. In that case, the end pointer would be beyond the end of the array and then this question comes into play. – chris Sep 17 '14 at 03:47

2 Answers2

4

You can use std::begin and std::end since c++ 11. For example:

int V[100];

std::sort(std::begin(V), std::end(V));
taocp
  • 23,276
  • 10
  • 49
  • 62
  • 3
    Prior to C++11, you can use V + (sizeof(V)/sizeof(V[0])) - 1 . – rcgldr Sep 17 '14 at 03:31
  • 1
    As chris explained in his comment under the question, the original code didn't sort the entire array, so it should at least be pointed out that this answer's code is not equivalent. Changing the array size is a weird thing to have done, and just confuses the issue. – Tony Delroy Sep 17 '14 at 03:34
  • 1
    @rcgldr, I wouldn't recommend it. That really shouldn't compile if you give it a pointer because it won't do the right thing, yet it does compile. Problem being that it's just way too easy to get a pointer from an array. Use `boost::begin` and `boost::end`, or make your own. They're both simple. Or you can make a function that only accepts arrays and returns the size. Note that for it to be equivalent to the answer, the `- 1` should disappear. – chris Sep 17 '14 at 03:34
1

There is another way in C style:

int V[101];

std::sort(V, V + sizeof(V)/sizeof(V[0]));
Krypton
  • 3,337
  • 5
  • 32
  • 52
  • Lose the -1. The iterator should point to one past the last element. Also note that this doesn't work for dynamically allocated arrays. – Drew Hall Sep 17 '14 at 03:36
  • 1
    +1 for your answer. `-1` matches the question - fair enough. IMHO, it's better to write ...`sizeof V / sizeof V[0]`... so there's only one place to maintain the array type... otherwise the code can easily become erroneous. `(` and `)` are only needed when `sizeof` is used on a type, not a variable. – Tony Delroy Sep 17 '14 at 03:39
  • This should have `- 1` on the end of the calculation; the question is asking how to get the address of the last element (not the one-past-the-end address). – M.M Sep 17 '14 at 03:44
  • yeah, it is equivalent yet more generic to use sizeof(V[0]) instead. – Krypton Sep 17 '14 at 03:44
  • @MattMcNabb: that's what the question asks, but that may well be because Lucas thinks `sort` should be told the first and last element to sort, rather than the first and 1-past-the-last `sort` actually needs.... A really good answer would explain the implications. – Tony Delroy Sep 17 '14 at 03:46