質問: MFCでCArray::SetSize関数の使い方が分からず困っています。 この関数の機能は、空または既存の配列のサイズを第一引数によって設定することは理解しましたが、 必要に応じてメモリに割り当てるという、第二引数の部分が理解できませんでした。 参考にしたMSDNのサイト: 第二引数のnGrowByは、サイズの増加が必要な場合に割り当てる要素スロットの最小数とありましたが、 ・サイズの増加とはどういう意味か? ・サイズの増加が必要な場合とはどういう場合か? ・割り当てる要素スロットとはどういう意味か? が分かりませんでした。 上記、教えて頂けるとありがたいです。 どうかよろしくお願いいたします。
回答: 前提知識として `CArray` (および標準 [c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") の `std::vector` ) は * 連続したメモリ領域を使うことで要素のランダムアクセスを `O(1)` かつキャッシュヒット率大で可能とする * 連続したメモリ領域の末尾に未使用領域を事前に置くことで、そこまではコストなしで拡張できる * 拡張の際 **未使用領域がなくなったら** 全データを別の場所に複写するしかないのでとても遅い(これを再配置と呼ぶ) という性質があります。 > > ・サイズの増加とはどういう意味か? > > ・サイズの増加が必要な場合とはどういう場合か? > > > 先の解説でいう再配置が生じるとき。 > > ・割り当てる要素スロットとはどういう意味か? > > > あなたのプログラムが `CArray` の拡張を随時行うロジックであるとき、再配置の後にも拡張を続ける可能性が高く、そうすると「再配置→拡張→再配置→拡張→再配置」が繰り返されることになり、とてつもなく遅くなります。頻繁な再配置を避けるには、十分余裕をもって再配置するとよいわけですが、その余裕分にどれだけの値を指定すると適切かは用途次第、つまりプログラマが自分で指定出来たほうが良いと Microsoft のエンジニアは判断したようです。「割り当てる要素スロット」とはその余裕分で、それを第二引数の `nGrowBy` で指定できるようになっています。 `nGrowBy` が * `-1` (や負数) のとき、現在のスロット増加分を変更しません * `0` のとき Microsoft の決めたロジックでスロットを増加させます (現実装では `4` または `m_nSize/8` または `1024`) * `正数` のとき、その個数分でスロットを増加させます