2

私はこの小さなプログラムを作成して、配列を練習しました。これは、最大10文字で、末尾が\0であると想定されています。動作しますが、動作が良すぎて、50文字の名前を入れても、正しい入力を吐き出します。何が得られますか?

#include <stdio.h>


int main(int argc, char const *argv[])
{
char name[11];

printf("Enter your name: ");
scanf("%s", name);

printf("Hi, %s\n", name);   
return 0;
}
4

2 に答える 2

8

割り当てた配列の終わりを超えて上書きしています。scanfの一部として、読み取る文字列の長さを指定して、文字列が収まるようにする必要があります。

scanf("%10s", name);

コードの改善点は、常に適切なサイズになるようにフォーマット文字列を生成することです。

#include <stdio.h>


int main(int argc, char const *argv[])
{
char name[11];
char formatstr[50];

snprintf(formatstr, sizeof(formatstr), "%%%ds", sizeof(name)-1);

printf("Enter your name: ");
scanf(formatstr, name);

printf("Hi, %s\n", name);
return 0;
}
于 2012-08-28T00:47:45.533 に答える
1

Cで配列を割り当てると、メモリのブロックの開始メモリアドレスを取得するだけで、使用できるようになることが保証されます。それ以上のことはありません。この保証は、この配列を使用して、境界の外側にあるメモリ位置の読み取り/書き込みを行わないという前提に基づいています。

JavaC#などの高級言語では、配列の境界外のメモリ位置にアクセスしようとすると、例外(エラー)がスローされます。残念ながら、Cでは自分自身です。

あなたの例は無害に見えますが、この種のアクセス違反はソフトウェア開発の一般的なバグであり、単純な誤動作から偶発的なスタックオーバーフローにつながる可能性があります。

于 2012-08-28T01:03:44.580 に答える