0

このスニペットを見てください:

#include <string>
#include <iostream>
#include <vector>

using namespace std;

class base {
public:
  string foo;
  base() {};
  base(const base &orig) {
    this->foo = orig.foo;
  };
 ~base() {} ;
};

class derived : public base {
public:
  string bar;
  derived(const derived &orig) : base(orig) {
    this->bar = orig.bar;
  }
  derived() : base() {} ;
  ~derived() {};
};

void asd(derived d)
{
    // works fine
    cout << d.foo << d.bar << endl;
}

int main(void)
{
    vector<derived> v;

    derived bla;

    bla.foo = "Test ";
    bla.bar = "String ";

    v.push_back(bla);

    asd(bla);

    // Why the hell does v.end()->foo and v.end()->bar segfault?!
    cout << v.end()->foo;
    cout << v.end()->bar << endl;
}

セグメンテーション違反が発生するのはなぜですか? これはコンソール出力です (g++ -o test test.cpp -g でコンパイル)

./test
Test String 
zsh: segmentation fault  ./test

v.end() 派生クラスの this ポインターが正しい位置を指していません...しかし、なぜですか?

4

2 に答える 2

13

end()最後の要素を指す反復子ではありません。最後の要素の 1 つ後ろを指します。逆参照end()は違法です。

back()最後の要素が必要な場合に使用します。

于 2012-12-16T15:15:18.297 に答える
3

your problem is the use of v.end().

quoted from here

Return iterator to end Returns an iterator referring to the past-the-end element in the vector container.

The past-the-end element is the theoretical element that would follow the last element in the vector. It does not point to any element, and thus shall not be dereferenced.

Because the ranges used by functions of the standard library do not include the element pointed by their closing iterator, this function is often used in combination with vector::begin to specify a range including all the elements in the container.

If the container is empty, this function returns the same as vector::begin.

use v[0] instead. (for this specific test, see other suggestions for vector getters in the quoted page).

于 2012-12-16T15:24:29.807 に答える