Using operator[] on empty std::vector

前端 未结 7 1013
迷失自我
迷失自我 2021-01-12 05:29

I was advised a while ago that is was common place to use std::vector as exception safe dynamic array in c++ rather than allocating raw arrays... for exampl

7条回答
  •  我在风中等你
    2021-01-12 06:24

    As far as the C++ standard is concerned, operator[] isn't guaranteed not to check, it's just that (unlike at()) it's not guaranteed to check.

    You'd expect that in a non-checking implementation, &scoped_array[scoped_array.size()] would result in a legal pointer either within or one-off-the-end of an array allocated by the vector. This isn't explicitly guaranteed, but for a given implementation you could verify by looking at its source. For an empty vector, there might not be an allocation at all (as an optimisation), and I don't see anything in the vector part of the standard which defines the result of scoped_array[0] other than table 68.

    Going from table 68, you might say that the result of your expression is &*(a.begin() + 0), which illegally dereferences an off-the-end iterator. If your implementation's vector iterator is just a pointer then you probably get away with this - if not you might not, and obviously yours isn't.

    I forget the results of the argument as to whether &*, on a pointer that must not be dereferenced, is a no-op, or not. IIRC it's not clear from the standard (some ambiguity somewhere), which provoked requests to fix the standard to make it explicitly legal. This suggests that it does in fact work on all or most known implementations.

    Personally I wouldn't rely on this, and I wouldn't disable the checking. I'd rewrite your code:

    char* pointer = (scoped_array.size() > 0) ? &scoped_array[0] : 0;
    

    Or in this case just:

    char* pointer = (n > 0) ? &scoped_array[0] : 0;
    

    It just looks wrong to me to use index n of a vector without knowing that the size is at least n+1, regardless of whether it actually works in your implementation once you've disabled the checking.

提交回复
热议问题