質問: sizeof(xx); strcat_s(xx, strlen(xx), y); //ここの関数で書き込みアクセスエラーが出ます。 cout << xx; return "a"; } int main() { cout << f("abc", "abcc"); _getch(); return 0; } ```
回答: 2つ誤りがあると考えます。 1. 呼び出し元で渡している引数`"abc"`には結合後の文字列`"abcabcc"`"を格納するだけのサイズがない可能性があります。 2. 呼び出し元では文字列定数を渡していますが、多くのコンパイラでは文字列定数を変更不能なメモリ領域に配置することが多いため、結合する際にアクセスエラーになる可能性があります。 動作させるには、次の2つのどちらかの修正を行うとよいと思います。 #一長一短です。後者はメモリリークの可能性があるので、前者の方が比較的よいと思います。 1. 呼び出し元で`"abc"`を結合後の文字数以上の配列に格納してテンプレート関数を呼び出す 追記 コメントの指摘通り、案1のコード例で配列`z`のサイズ計算が間違ってました。例を訂正します。 (`sizeof(xx)`だと`sizeof(const char*)`なので、期待通りになりません) ``` int main() { const char xx[] = "abc"; const char yy[] = "abcc"; // 必要最小限のサイズより大きくなるのは割り切りです。 char z[sizeof(xx) + sizeof(yy)] = "abc"; cout << f(&z[0], &yy[0]); // 以下、略 } ``` 2. テンプレート関数内で動的に結果配列を生成しそれを返す ``` template<> const char* f(const char* x, const char* y) { char* z = new char[strlen(x) + strlen(y) + 1]; strcpy(z, x); strcat(z, y); // zは呼び出し元でdeleteする必要がある。 return z; } ``` また、`rsize_t`と`size_t`の違いですが、机上で確認した限りだと、 1. `RSIZE_MAX`という現実的な上限値が規定されている。 2. `rsize_t`の値を返す関数は`RSIZE_MAX`を超える結果の場合`0`を返すことができる。 という違いがあるように見えました。 ただし、これはC言語の規格(「C11」の規格)であり、C++言語では規格化されていないように見えましたので、コンパイラ(処理系)によっては対応していないかも知れません。