C++のvector要素を空にする方法について

AI実装検定のご案内

C++でvectorを「空にする」と言っても、実際にはいくつか意味があります。

ここを曖昧にしたまま覚えると混乱しやすいので、まず整理しておくのが大切です。

vectorを空にする話では、主に次の4つを区別して考えます。

  1. 要素をすべて削除して、要素数を0にする
  2. 要素数はそのままで、中身の値だけ初期化する
  3. 要素を削除するだけでなく、確保しているメモリもできるだけ減らす
  4. 全体ではなく、一部の要素だけ削除する

この違いを理解すると、どの方法を使うべきかがはっきりします。

目次

要素をすべて削除して空にする

もっとも基本的な方法は、vectorに入っている要素をすべて削除して、要素数を0にする方法です。

この操作を行うと、vectorの中身はなくなり、size()は0になります。

つまり「要素は空」になります。

ただし、ここで重要なのは、要素数が0になることと、確保しているメモリがなくなることは別だという点です。

vectorは内部的に、将来の追加に備えてメモリ領域を確保していることがあります。

要素を全部消しても、その確保済み領域は通常そのまま残ります。

そのため、見た目には空でも、内部では追加のための領域をまだ持っていることがあります。

この方法は、次のような場面に向いています。

  • いったん中身を消したい
  • その後また要素を追加する予定がある
  • 再利用したいので、メモリを残しておいてもよい

実務でも、この「要素だけ全部消す」方法がもっともよく使われます。

要素数はそのままで、中身だけ空っぽの状態にしたい

場合によっては、要素そのものを削除したいのではなく、要素数は維持したまま、中身だけ初期値に戻したいことがあります。

たとえば、整数のvectorなら、全要素を0にしたいというケースです。

この場合は「削除」ではなく「値の書き換え」を行います。

ここで大事なのは、これは厳密にはvectorを空にしているわけではない、ということです。

要素はまだ存在していて、ただ中身が初期化されているだけです。

たとえば、要素数が5のまま全要素を0にした場合、そのvectorは空ではありません。

size()は5のままです。

したがって、「中身を消す」と「要素をなくす」は別物です。

この考え方は次のような場面で使います。

  • 配列の長さは変えたくない
  • 値だけリセットしたい
  • その後、同じ大きさのまま再利用したい

初心者が混同しやすいポイントですが、要素数を0にすることと、各要素の値を初期値にすることは違います。

メモリもできるだけ解放したい

要素を全部消しただけでは、通常は内部で確保していた領域が残ります。

そのため、「本当に空っぽにしたい」「メモリ使用量も減らしたい」という場合は、もう一段階別の考え方が必要です。

この場合は、要素を削除したうえで、余分な容量も縮める方向で処理します。

ただし、ここで気をつけたいのは、メモリの解放は方法によって性質が違うことです。

余分な容量を減らすよう要求する方法

vectorには、不要になった容量を減らすよう実装に依頼する方法があります。

ただし、これは「必ず縮む」と保証されているわけではありません。

あくまで「縮めてほしい」という要求です。

そのため、この方法を使っても、環境や実装によっては期待通りに容量が減らないことがあります。

空のvectorと入れ替える考え方

別の考え方として、空のvectorと現在のvectorを入れ替える方法があります。

この方法では、元の大きなメモリ領域を空の一時オブジェクト側へ移し、その一時オブジェクトが破棄されることで、結果としてメモリ解放が期待できます。

この方法は、昔から「要素だけでなく内部領域も手放したい」ときの定番としてよく知られています。

ただし、ここでも本質は「空になること」よりも「不要な領域の解放を期待できること」にあります。

「容量が必ず0になる」とまで強く言い切るより、メモリ解放を狙う方法と理解しておくのが正確です。

特定の要素だけ削除したい

「空にする」という話から少し広がりますが、vectorでは全体ではなく一部だけを削除したいこともよくあります。

たとえば、

  • 先頭から何個かだけ消したい
  • ある位置の要素だけ削除したい
  • 特定の値を持つ要素を全部取り除きたい
  • 条件に合う要素だけ消したい

といったケースです。

この場合は、vector全体を空にするのではなく、一部だけ削除する操作を使います。

ここで知っておきたいのは、vectorは配列に近い連続領域を使っているため、途中の要素を削除すると、後ろの要素が前に詰められることです。

そのため、末尾以外の削除では要素の移動コストが発生します。

つまり、vectorは末尾への追加や削除には強い一方で、途中削除は軽くないことがあります。

clearと「値の初期化」の違い

この部分は特に重要です。

vectorを空にしたいというとき、初心者がよく混同するのが次の2つです。

  • 要素そのものを削除する
  • 要素は残したまま、中の値だけ初期化する

前者では、size()は0になります。

後者では、size()は変わりません。

たとえば、10個の整数を持つvectorの値をすべて0にしても、それは空のvectorではありません。
要素数は10のままです。

そのため、「空にしたい」という言葉を使うときは、本当に要素数を0にしたいのか、それとも中身をリセットしたいだけなのかを区別することが大切です。

clearとメモリ解放の関係

ここも非常に誤解が多い部分です。

要素を全部削除する操作をしても、通常は確保済みの容量はそのまま残ります。

これは無駄ではなく、次に再び要素を追加するときに再確保を減らして効率よく動くための設計です。

つまり、要素が空になったからといって、メモリ使用量まで必ず最小になるわけではありません。

この性質は次のように理解すると分かりやすいです。

  • size は現在入っている要素数
  • capacity は今後の追加に備えて確保されている領域の大きさ

要素を削除する操作は、通常はsizeを減らします。

しかし、capacityまでは自動で減らさないのが普通です。

この違いを知っておくと、「空にしたのにメモリが減らない」と感じたときの理由が理解しやすくなります。

空かどうかの判定

vectorが空かどうかを調べたいときは、要素数が0かどうかを見ることになります。

ここで大事なのは、空というのは要素数が0であることを意味するという点です。

中身の値が全部0であっても、要素数が残っていれば空ではありません。

つまり、空判定は「値」ではなく「要素数」に基づいて行います。

よくある誤解

要素を全部削除すればメモリもなくなる

これは正確ではありません。

通常は要素数が0になるだけで、確保済み領域は残ります。

中身を0にすれば空になる

これも誤りです。

値が初期化されただけで、要素自体は存在しています。

一部の削除と全削除は同じ

一部削除は、位置や条件を指定して特定の要素だけ消す操作です。

全削除は、全要素をなくして要素数を0にする操作です。

目的が違います。

新しく同じ名前で宣言し直せば空にできる

これは既存のvectorを空にする操作ではありません。

同じスコープなら再宣言エラーになりますし、そもそも「変数を空にする処理」とは別物です。

実務での使い分け

実務では、まず「何を空にしたいのか」を考えます。

ただ中身の要素を全部消したい

この場合は、要素数を0にする基本の方法を使います。

もっともシンプルで、再利用にも向いています。

要素数は残したまま値だけリセットしたい

この場合は、削除ではなく、各要素の値を書き換える方法を使います。

大きなデータを処理したあとで、メモリも手放したい

この場合は、要素削除だけでなく、余分な容量を減らす方法や、空のvectorと入れ替える方法を検討します。

特定の要素だけ消したい

この場合は、全削除ではなく、位置や条件を指定した削除方法を使います。

最近のC++で補足しておきたいこと

近年のC++では、特定の値や条件に合う要素を削除するための、より簡潔な書き方も使えるようになっています。

そのため、古典的な書き方だけでなく、新しい標準の機能も知っておくと便利です。

ただし、古くからある方法が間違っているわけではありません。

今でも十分に正しい書き方です。

新しい書き方は、より読みやすく簡潔になる選択肢と考えると分かりやすいです。

まとめ

C++のvectorを「空にする」ときは、まず何を意味しているのかをはっきりさせることが重要です。

  • 要素を全部削除して要素数を0にしたいのか
  • 要素数はそのままで中身だけ初期化したいのか
  • メモリもできるだけ減らしたいのか
  • 特定の要素だけ削除したいのか

この違いによって選ぶ方法は変わります。

特に重要なのは次の3点です。

  • 要素を削除しても、通常は確保済みメモリまでは自動で減らない
  • 値を初期化しても、要素数が残っていれば空ではない
  • 「空」とは、要素数が0であることを意味する

この3つを押さえておけば、vectorの扱いで大きく迷いにくくなります。

以上、C++のvector要素を空にする方法についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次