何にハマったの?
クラスのコピーの時にポインタ渡しをするコードを書いたら、vectorでの使用時に想定と違う挙動が起きた。
詳しくは下を見てください。
サンプルコード
#include<cstdlib>
#include<cstdio>
#include<vector>
class A{
public:
float *p;
A(int d){
p = new float[d];
return;
}
~A(void){
delete p;
return;
}
void copy(const A &rhs){
this->p = rhs.p;
return;
}
A(const A &rhs){
copy(rhs);
}
A& operator=(const A &rhs){
copy(rhs);
return *this;
}
};
int main(void){
std::vector<A> tmp(3, A(2));
printf("%lf\n", tmp[1].p[0]);
tmp[0].p[0] = 1.0;
printf("%lf\n", tmp[1].p[0]);
return 0;
}
newした後に配列の初期化してないとか色々省いてますが許して。。。
実行結果
0.000000
1.000000
free(): double free detected in tcache 2
tmp[0]の値を変えてるだけなのにtmp[1]の値が変わる???
原因
C++日本語リファレンスを読むと、vectorのコンストラクト時の挙動は
value のコピーを n 個要素として保持した vector オブジェクトを構築する。
とあるように、vectorの各要素の初期化はコピーで行われるらしい?
https://cpprefjp.github.io/reference/vector/vector/op_constructor.html
試しに
printf("%p %p %p\n", tmp[0].p, tmp[1].p, tmp[2].p);
とかやってみるとアドレスが全部同じなのが確認できます。