1

重複
の可能性:sizeof(配列を指すポインター)を見つける方法

strcpy_sの最初の呼び出しでは、コンパイラは配列の長さを推測できますが、2番目の呼び出しでは、配列の長さを渡す必要があります。

TCHAR szTemp[512];
::strcpy_s(szTemp, "a long text message");

TCHAR* pszTemp = new TCHAR[512];
::strcpy_s(pszTemp, 512, "a long text message");
delete []pszTemp;

コンパイラはこれをどのように行いますか?これはMicrosoftのみの拡張機能ですか?また、パラメータの控除を利用するようにメソッドを宣言するにはどうすればよいですか?

4

5 に答える 5

6

の最初の使用ではstrcpy_s、配列内の要素の数はszTempタイプの一部であるためszTemp(「512の配列TCHAR」であるため)、コンパイラはそれを認識し、を宣言するテンプレートを完成させることができますstrcpy_s

の2番目の使用法ではstrcpy_spszTempはポインタ(「へのポインタTCHAR」)であり、配列ではなく、ポイントされる要素の数は型の一部ではありません。一般に、コンパイラーは、ポインターが指す場所にある要素の数を知ることができません。(この場合、前のコードが示しているので、コンパイラーはそれを推測するかもしれませんが、それはコンパイラーと一般的に実装する価値がないと見なされる言語に複雑さを追加します。)

これを自分で行うには、次のように宣言された方法でテンプレートstrcpy_sを宣言します。

template <size_t size> errno_t strcpy_s(
    char (&strDestination)[size],
    const char *strSource 
); 

これは、パラメーターに基づいてテンプレートを宣言します。テンプレートは、最初のパラメーターのタイプが「の要素のsize配列への参照」である関数用です。コンパイラは、charの512要素の配列である最初の引数での使用を確認すると、この引数をテンプレートのパラメータに一致させることができ、512であると推測します。sizecharstrcpy_ssize

他の場所では、(宣言だけでなく)テンプレートの定義があります。sizeその定義では、コードでテンプレートパラメータを使用できます。コンパイラがの使用を確認すると、 512strcpy_sの特殊化でテンプレート定義をインスタンス化します。size

Cにはテンプレートがないため、これはCではなくC++でのみ機能します。

于 2012-12-12T19:51:25.403 に答える
2

ドキュメントによるとstrcpy_s、は具体的な関数として存在するだけでなく、指定した配列など、既知のサイズの配列に対してオーバーロードされたテンプレート関数としても存在しszTempます。その場合、配列のサイズは関数定義のテンプレートパラメーターです。

strcpy_sはそれ自体がMicrosoft専用の関数であるため、テンプレートのバージョンは、ポインターを受け入れるバージョンよりもMicrosoft固有のものではありません。

于 2012-12-12T19:48:14.350 に答える
1

1つ目は、次のようなテンプレートを使用することです。

template <size_t N>
strcpy_s(char (&dest)[N], char const *source) { 
    // ...
}

テンプレート内にNは、渡された配列のサイズがあります。

2番目のケースでpszTempは、は配列ではなくポインターであるため、テンプレートパラメーター(実際の配列が必要)と一致しないため、宛先サイズを明示的に渡す必要があります。

于 2012-12-12T19:49:33.213 に答える
1

最初のケースでは、テンプレート関数が使用されているため(doc)、魔法はありません。

template <size_t size>
errno_t strcpy_s(
   char (&strDestination)[size],
   const char *strSource 
); // C++ only
于 2012-12-12T19:50:38.750 に答える
1

配列として宣言されているため、szTempの配列の長さを推測できます。pszTempの場合、ポインターとして宣言されており、その長さを推測する方法はありません。

おそらくいくつかのサードパーティのstrcpy_s実装がありますが、ほとんどはMicrosoftのものであり、セキュリティホールを強化するための努力の一環でした。

于 2012-12-12T19:50:55.427 に答える