scanf_s関数には バッファオーバーフローを防ぐため入力文字数制限機能が付けられています

アレサ「再びですが


scanf関数をつかって配列に文字列をとりこむために


配列宣言

char hairetu[100];

おこなって

配列変数を

100個用意したとします


ここでは


プログラムの入力、実行に


統合開発環境Visual Studioをつかってみましょう。


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void) {

char hairetu[100];

printf("文字列を入力してください\n");

scanf("%s", hairetu);


printf("%s", hairetu);


return 0;

}


Visual Studioの場合


ビルド結果


文字列を入力してください

パズルでやっほう(と入力すると)

パズルでやっほう


この場合


char hairetu[100];


により生成される配列変数

char hairetu[0]

char hairetu[1]

char hairetu[2]

char hairetu[98]

char hairetu[99]


には99の文字と


文字列であることをコンピュータに認識させるナル文字\0


を格納することができるので


8文字の文字列


パズルでやっほう


は余裕をもって


格納することができます


では


100文字以上の文字を入力した場合どうなるでしょうか?


ためしてみましょう。


#pragma warning(disable: 4996)


#include <stdio.h>


int main(void) {

char hairetu[100];

printf("文字を入力してください\n");

scanf("%s", hairetu);


printf("%s", hairetu);


return 0;

}


コンパイル結果

文字を入力してください

パズルでやっほう~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(と入力すると)

パズルでやっほう~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


なんだか


統合開発環境Visual Studioでは


他社のコンパイラと比べて


かなり多くの文字列を


scanf関数をつかってメモリに格納


printf出力表示することができています。



このとき

統合開発環境Visual Studioでは


警告文で


stack around the variable 'hairetu' was corrupted.


と表示されます


配列hairetuの周りのメモリのデータが破壊されたという意味ですね


このコンパイル結果をみてもわかるように


配列char hairetu[100]で生成される


配列変数(つまりメモリ)には


99の文字と


99の文字が文字列であることをコンピュータに認識させるナル文字\0


しか格納できないのですが


それよりも多くの文字が


コンピュータのメモリに格納され


printf出力表示ができています


このとき用意したchar hairetu[100]に入りきなかった文字


は自動的に


周りのメモリに格納されていたデータに


上書きされて格納されています。


この状態を


バッファオーバーフローとよびます


バッファとはデータが1時的に保存されるメモリのことを表しています


ですから


周りに重要なデータがあるときは


困ってしまいますの。


ですから


マイクロソフト社が独自に開発した


scanf_s関数には


入力する文字列を制限する機能が付けられています


scanf_s関数は


scanf_s("%s",hairetu,5);


のような書式が用いられます。


このscanf_s関数の第3引数が


コマンドプロンプト画面から入力できる文字列の長さを制限しています。


このscanf_s関数の第3引数に5と記述された場合は


ナル文字\0が自動的にhairetuに格納されるので


4文字までの文字列を格納することができます。


もし

4文字を超える文字列を入力すると


1文字も配列に格納されないように設定されており


コンパイルしても


コマンドプロント画面には何も表示されません。


セキュリテイ機能が強化されているため



1文字を変数に格納するときと違い


普通のscanf関数のように第3引数を記述せず


scanf_s("%s",hairetu);


のように記述することはできません



このような仕組みとなっているため


scanf_s関数をつかえば


コマンドプロンプト画面から入力される文字がながすぎるため


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


バッファオーバーフローにより


破壊されるということがないというわけですね。」






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

作者を応援しよう!

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

応援したユーザー

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