strcpy_s関数とstrcpy関数の違いはなんでしょうか?

ソーラー「そこで


strcpy_s関数とstrcpy関数の違いはなにかということなります


strcpy_s関数はセキュリティ機能を強化した関数で


strcpy_s(str,12, ars);


のように


第2引数をもつことができます。


strcpy_s(str,12, ars);



配列strに配列arsに格納されている文字列データを


格納する働きがあります


ここで


第2引数の12は12バイトを意味しており


配列strに書き込まれる文字列データの数を


12バイトまでと制限しています



#include <stdio.h>

#include <string.h>


int main(void) {


char str[100];

char ars[100];

char arr[100];


strcpy_s(str, "luckyで~す");

strcpy_s(ars, "mappyで~す");

strcpy_s(arr, "benriで~す");



strcpy_s(str,12, ars);

/*配列strに書き込まれる文字列データの数を12バイトまでと制限しています*/

printf("%s\n", str);

printf("%s\n", ars);

printf("%s\n", arr);


return 0;

}


ビルド結果


mappyで~す

mappyで~す

benriで~す



ソーラー「配列arsに格納されている文字列データは


"mappyで~す"



文字列データ"mappyで~す"が


文字列データであることを示す\0(ナル文字)を含めて


12バイトのデータ容量があります。


strcpy_s(str,12, ars);


により


配列strには12バイトまでの文字列データを書き込むことができるので


12バイトのデータ容量をもつ


"mappyで~す"



無事に


配列strに書き込まれています。


ここで


strcpy_s(str,2, ars);



配列strに書き込むことのできる


文字列データを2バイトに制限したとすると


ビルド結果はどうなるかな?


新たな次のプログラムを実行してみよう。


#include <stdio.h>

#include <string.h>


int main(void) {


char str[100];

char ars[100];

char arr[100];


strcpy_s(str, "luckyで~す");

strcpy_s(ars, "mappyで~す");

strcpy_s(arr, "benriで~す");


printf("実行されるのはこの命令文までです\n");

strcpy_s(str, 2, ars);



/*配列strに書き込まれる文字列データの数を12バイトまでと制限しています*/

printf("%s\n", str);

printf("%s\n", ars);

printf("%s\n", arr);


return 0;

}



ビルド結果



Debug Assertion Failed!


Program:

C:\Users\solarplexuss\source\repos\Project8\Debug\Project8.exe


File:minkerne|\crts\ucrt\inc\corecrt_interanal_string_templates.h


Line:81


Expression:(L"Buffer is too small"&&0)


For information on how your program can cause an assertion failure,see the Visual C++ documentation on asserts.


(Press Retry to debug the application)



中止  再試行  無視



と表示されます。



ここで

中止 無視のいずれかを選んでも





        実行されるのはこの命令文までです






コマンドプロンプト画面に表示されます。


つまり



strcpy_s(str, 2, ars);

の前の命令文

printf("実行されるのはこの命令文までです\n");


までしか


プログラムが実行されないのです



strcpy_s(str, 2, ars);


では


配列strに書き込むことのできる文字列データは2バイトまでと制限されているので


今のプログラムのように


配列arsに格納されている文字列データ


"mappyで~す"(12バイト)を


配列strに格納しようとすると


strcpy_s(str, 2, ars);


は実行されず


それ以降の


プログラムの実行がされないよう設計されています。」


アレサ「なぜこのようなことがおこるのですか?(*^_^*)/」


ソーラー「よくぞ  きいてくれました


娘や・・・


それをまっていました


ここまでひっぱったかいがあるというものだね・・・




それは😊

strcpy関数では


strcpy(str, ars);


のように


配列strに入力できる文字列データを制限できません。


もしも


char str[100];

char ars[100];

char arr[100];


でなく


char str[100];

char ars[200];

char arr[300];

と配列宣言がされていて


配列arsに150バイトのデータ量をもつ文字列データが格納されていた場合


strcpy(str, ars);


が実行されると


100バイトしかデータ格納容量のない配列strに


150バイトのデータ量をもつ文字列データが格納されることになります。


配列strは100バイトしかデータ格納容量がないので


配列strで格納できない残り50バイトのデータは


別のメモリにあふれて格納されることになります。


つまり


配列strの周りのメモリに格納されているデータが


書き換えられてしまうというわけです


もしも重要なデータだったらまずいよね。


そこで

strcpy関数を改良した

strcpy_s関数が考案され


配列strに書き込まれる文字列データを制限できるようにし


制限を超える文字列データが


配列strに格納されようとすると


strcpy_s関数の命令文の実行を止めて


配列strの周りのメモリに格納されているデータが


書き換えられてしまわないようにしたというわけです。」










  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます