C++ での文字列の sizeof 演算子と strlen 関数の違い

胡金庫 2023年10月12日
  1. sizeof オペレーターの特性と使用シナリオ
  2. std::string::size メンバー関数を使用して、文字列の文字数を取得する
C++ での文字列の sizeof 演算子と strlen 関数の違い

この記事では、C++ の文字列で strlen 関数を使用するのではなく、sizeof 演算子を使用する場合の複数の違いを示します。

sizeof オペレーターの特性と使用シナリオ

sizeof 演算子は、指定された式またはデータ型のストレージサイズを取得する単項演算子です。この演算子はオブジェクトサイズをバイト単位で評価し、sizeof(char)1 であることが保証されています。

1 バイトは常に 8 ビットに等しいという誤った考えがあり、その結果、オブジェクトのサイズをビット単位で計算できます。実際には、言語自体によって 1 バイトが 8 ビットであるとは保証されていません。これは主に、基盤となるハードウェアプラットフォームに依存します。それでも、最新の汎用ハードウェアのほとんどは 8 ビットバイトを使用しています。

sizeof 演算子は、関数または不完全な型またはビットフィールドを含む式には適用できないことに注意してください。次のサンプルコードでは、sizeof 演算子を異なるタイプの 2つの配列に適用します。結果は、プラットフォームでも同じになる可能性があります。char のサイズは 1 バイトであることが保証されているため、20 文字の配列は 20 バイトを使用します。

一方、long long データ型は実装定義であり、この場合、たまたま 8 バイトです。したがって、配列の合計サイズは 160 バイトです。次の例の最後の行に示すように、配列全体の sizeofsizeof の 1つの要素で除算することによって、配列内の要素の数を求めることもできることに注意してください。

#include <iostream>

using std::cout;
using std::endl;

int main() {
  char arr[20];
  long long arr2[20];

  cout << "sizeof ( array of 20 long longs ) : " << sizeof arr << endl;
  cout << "sizeof ( array of 20 long longs ) : " << sizeof arr2 << endl;
  cout << "length of array of 20 chars)      : "
       << ((sizeof arr) / (sizeof arr[0])) << endl;
  cout << "length of array of 20 long longs ): "
       << ((sizeof arr2) / (sizeof arr2[0])) << endl;

  return EXIT_SUCCESS;
}

出力:

sizeof ( array of 20 long longs ) : 20
sizeof ( array of 20 long longs ) : 160
length of array of 20 chars)      : 20
length of array of 20 long longs ): 20

sizeof 演算子を使用して文字列の長さを求めるのは間違っています。C++ の文字列の 2つの表現タイプ、文字列と std::string クラスについて考えてみましょう。前者は主に char ポインタを使用してアクセスされ、sizeof を適用すると、文字列全体ではなく、ポインタ自体のストレージサイズが取得されます。

sizeof 演算子を使用して std::string オブジェクトのサイズを取得しようとすると、オブジェクトのストレージサイズが取得されます。これは、以下のコードスニペットに示されている文字列の文字数ではありません。

#include <cstring>
#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

int main() {
  const char *text1 = "arbitrary string value 1";
  string text2 = "arbitrary string value 2";

  cout << "sizeof char* : " << sizeof text1 << endl;
  cout << "sizeof string: " << sizeof text2 << endl;
  cout << "sizeof string.data: " << sizeof text2.data() << endl;

  return EXIT_SUCCESS;
}

出力:

sizeof char* : 8
sizeof string: 32
sizeof string.data: 8

次に、C 文字列ライブラリの残骸である strlen 関数を取得しました。指定された文字列の長さを計算し、関数はバイト数を整数値として返します。strlen は、有効な文字列が格納されている char ポインタ、または std::string::c_str によって返される値に適用できますが、C++ プログラマの選択ではありません。

#include <cstring>
#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

int main() {
  const char *text1 = "arbitrary string value 1";
  string text2 = "arbitrary string value 2";

  cout << "strlen char* : " << strlen(text1) << endl;
  cout << "strlen string: " << strlen(text2.c_str()) << endl;

  return EXIT_SUCCESS;
}

出力:

strlen char* : 24
strlen string: 24

std::string::size メンバー関数を使用して、文字列の文字数を取得する

それどころか、C++ プログラマーは、文字列を処理するためのより安全なメソッドを提供するため、std::string クラスの size メンバー関数を利用する必要があります。文字列がある場合は、size メンバー関数を使用することもできます。新しい string オブジェクトを作成し、戻り値に対して size 関数を直接呼び出す必要があります。次のコード例は、両方のシナリオの主な使用法を示しています。

#include <cstring>
#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

int main() {
  const char *text1 = "arbitrary string value 1";
  string text2 = "arbitrary string value 2";

  cout << "length char* : " << string(text1).size() << endl;
  cout << "length string: " << text2.size() << endl;

  return EXIT_SUCCESS;
}

出力:

length char* : 24
length string: 24
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ String