アルパカ三銃士

〜アルパカに酔いしれる獣たちへ捧げる〜

ポインタで vector を作ってはいけないかもしれない

この issue を解決しようとしてデバッグしまくってた結果疑問が出てきた。

github.com

それは STLvector でポインタを使ってはいけない疑惑。

Compiler::Lexer では次のようなクラスを定義することで token を管理している。

class Tokens : public std::vector<Token *> {
public:

    Tokens(void) {}
    inline void add(Token *token) {
        if (token) push_back(token);
    }

    inline void remove(size_t) {
        //erase(idx);
    }

    inline Token *lastToken(void) {
        return (size() > 0) ? back() : NULL;
    }
};

このように Token という型の vector を用意し、見つけた token を add メソッドを使って格納していくのだが、これを行う回数が多くなった場合、次の画像のようにデータの破損が生じる。

f:id:codehex:20180104234419p:plain

これは vector であらかじめ確保していた領域が push_back を用いてメモリ領域が足りなくなった時に、再確保を行おうと格納されていたデータのメモリ領域までも破壊してしまって起こる症状らしい。

この問題を回避するためにスマートポインタを使えばいいらしいが、続きは解決したら書く。

続き

codehex.hateblo.jp

2018 1/17 追記

id:aiueo1145140 さんからコメントより指摘を受けました。こういう指摘はとても嬉しいです。
利用していたプロダクトが継承を行っていたため、それに沿って記述しています。 STL コンテナを継承してはいけない理由として以下の記事が参考になりました。

qiita.com