1. ホーム
  2. c++

[解決済み] char * (char配列)の実長と全長を求めるには?

2022-03-08 06:47:15

質問

の場合 char [] でその長さを簡単に求めることができる。

char a[] = "aaaaa";
int length = sizeof(a)/sizeof(char); // length=6

しかし、このようなことはできません。 char * によるものです。

char *a = new char[10];
int length = sizeof(a)/sizeof(char);

というのも、そうなんです。 a はポインターで、次のようなものです。 length は常に 4 (システムによって異なる)。

質問なんですが、どうやったら char * を後から追加することはできますか? という疑問を持たれるかもしれませんが、そのようなことはありません。 10 作ったばかりだからです。なぜなら、この長さを求めるステップは、作成してからずいぶん時間が経ってからになるかもしれないし、この数字を確認するために、ずいぶん前に戻ってきたくはないからです。さらに、本当の長さも知りたい。

より具体的に言うと

  • どうすればその実体を知ることができるのか length=5 ?
  • その合計を取得する方法 length=10 ?

を以下の例で説明します。

char *a = new char[10]; 
strcpy(a, "hello");

解決方法は?

無理です。とにかく100%の精度は無理です。ポインターは は長さ/大きさを持たず、それ自身の . それがすることは、charを保持するメモリ上の特定の場所を指すだけです。もしその文字が文字列の一部であるなら、その文字列を保持するために strlen を使えば、現在指されている文字に続く文字が何であるかを判断することができますが、だからといって 配列 の場合、それほど大きなサイズになります。
基本的には

A ポインタ 配列 というように 必要 は、配列のサイズを知っている必要があります。ポインタは1つの値を指すので、配列がなくてもポインタは存在できます。ポインタが指すメモリがどこにあるのかも気にしない(読み込み専用、ヒープ、スタック...関係ない)。ポインターは自分以外の長さを持たない。ポインターはただ...
これを考えてみましょう。

char beep = '\a';
void alert_user(const char *msg, char *signal); //for some reason
alert_user("Hear my super-awsome noise!", &beep); //passing pointer to single char!

void alert_user(const char *msg, char *signal)
{
    printf("%s%c\n", msg, *signal);
}

ポインターは1文字でも、配列の先頭、末尾、中間でも構いません。
文字列は構造体だと考えてください。ヒープ上に1つの構造体を割り当てることがあります。これも、配列のないポインタを作成します。

ポインタだけでは、それが指している配列の大きさを判断することは不可能です。最も近いのは calloc で、そのポインタから連続する"㊧"の数を数えるんです。もちろん、その配列のキーに何かを代入・再代入してしまうとうまくいきませんし、メモリが単に を保持している場合、その配列の \0 もあります。ですから、この方法を使うことは信頼性が低く、危険で、一般的に愚かなことなのです。やめてください。しないでください。しないでください。

もう一つの例え話。
ポインターは道路標識のようなもので、次の場所を指していると考えてください。 タウンX . 看板はその町がどんなところか知らないし、そこに誰が住んでいるかも知らないし、気にしない(気にしうる)。この看板の仕事は、あなたに次の場所を教えることです。 タウンX . その町がどのくらい遠いかはわかるが、どのくらい大きいかはわからない。その情報は道路標識には無関係と判断されます。それは町そのものを見ればわかることで、その方向を示す道路標識ではわからないのです

だから、ポインターを使うと......できるのは

char a_str[] = "hello";//{h,e,l,l,o,\0}
char *arr_ptr = &a_str[0];
printf("Get length of string -> %d\n", strlen(arr_ptr));

しかし、これはもちろん、配列/文字列が \0- 末端である場合にのみ機能します。

余談ですが

int length = sizeof(a)/sizeof(char);//sizeof char is guaranteed 1, so sizeof(a) is enough

は実際には size_t (の戻り値型)。 sizeof から int と書くのがベストです。

size_t length = sizeof(a)/sizeof(*a);//best use ptr's type -> good habit

以降 size_t は符号なし型であり、もし sizeof はより大きな値を返します。 length は、予想外のことが起こるかもしれない...。