2016-07-11 24 views
5

における範囲外(列)の後には、非常に単純なCプログラムであります配列への文字列以下は出力されます:格納データ動的に割り当てられた配列

String = Elephant 
String = ElephaDt 

明らかに、私は、OSのメモリMGMTは私がPに動的に割り当てられた空間の範囲外の多くの要素を格納することができ、なぜ知っているだけので、好奇心5つのchar型の要素のために要求さ 。私が5文字のスペースしか割り当てられなかった場合、strcpy()はどのようにして5文字以上のさらに大きな文字列 "Elephant"を格納することができましたか?

+4

Cには境界チェックがありません。境界から書き出すとコンパイラは不平を言うことはありません。それは*未定義の動作につながります*ので、しないでください。 –

+0

@ Joachim Pileborgは「文句を言っても文句を言いませんが...」という振る舞いが定義されています。確かに、Cは境界チェックを指定していませんが、コンパイラはそれを採用することがあります。境界からの書き出しはUBです。 – chux

+0

"なぜOSのメモリ管理によって、p内の動的に割り当てられた領域の範囲外にもっと多くの要素を格納することができましたか?" - >このような状況でコードが何をする必要があると思いますか? – chux

答えて

5

メモリが割り当てられるとき、これは一般にメモリマネージャによって行われます。これらはしばしば、OSからより大きいメモリチャンクを割り当てて、それをmalloc()や友人に小さな部分で渡します。

したがって、割り当てた5バイトは、より大きなメモリチャンクの一部です。より大きなチャンクではなく、割り当ての境界に違反したので、OSは干渉しません。しかし、近くの割り当てを上書きすることによって、あなた自身のプログラムの他のメモリを壊したことを意味する可能性があります。メモリマネージャが割り当てられたメモリと空きメモリを追跡するために使用するデータが破損している可能性もあります。しかし、それは与えられていません。これは単に未定義の動作です。

未定義の動作は、実行時エラーが発生する必要があるわけではありません。それは何も起こらないことを意味することもできますし、WW3などを始めることもできます。それは未定義ですが、必ずしもクラッシュを意味するものではありません。

2

Cでプログラムしたいのであれば、それに慣れる必要があります(たとえば、配列が範囲外になるなど)がありますが、実際には言語のルールに違反している場合は、 undefined behaviorをトリガーします。

これは、コンパイラは常にそのことについて警告を表示しないことも確かに助けていません。

これは、ほとんどの時間は、あなた自身がこれらの規則に違反しないよう注意する必要があるどれだけ言語の作品です。 strcpy()を使用することにより

0

は、ユーザーが定義する宛先にしたい文字数をコピーします。配列の境界をチェックしません。それは単に単語全体をコピーするまでコピーを保持します。


これは、コンパイルエラーなしで実行できることを意味します。あなたが割り当てられたメモリの境界外に何が起こるかを確認することはできませんしかし、これは、(それを理解するためにthis linkを参照)を呼び出します。あなたのケースでは何も悪いことは起こりませんでした(実際に何が起こったかはあなたのものでした)が、あなたは一般的には確信できません。

-1

動的に割り当てる配列は、ヒープメモリから割り当てられています。 @Rudy Velthuisが言及したように、ヒープメモリは大きな塊で割り当てられます。したがって、通常のシナリオでは、プログラムは正常に動作しています。しかし、という厳しい状況があり、コンピュータのほとんどのメモリが占​​有されているシナリオを考えてみましょう。その時点で、ヒープ内のあるプロセスのメモリチャンクがヒープチャンクの隣に存在し、プロセスに割り当てられる可能性が高くなります。状況をさらに確率的にすると、配列がヒープの最端で割り当てられ、割り当てられたメモリの終わりを超えてアクセスすると、プログラムは他のプログラムのヒープにアクセスします。この場合、OSはステップインしてプログラムへのアクセスを拒否し、プログラムがクラッシュします。

希望、それはあなたを助けます。

+0

Downvoter、downvotingの理由を教えてください。 –

+0

あなたのプログラムは、一度コンパイルされると、緊密でないメモリの状況でまったく同じように動作します。 – tofro

+0

@tofro、私は仮説的なシナリオを説明しました。さらに、私は個人的に同じことを経験しました。ターボコンパイルを使用してコンパイルされたプログラムは、境界を超えてメモリにアクセスし、ときどきクラッシュし、時にはうまくいきました。私は実行可能ファイルをあなたに紹介することができたらいいと思う。 –

関連する問題