好奇心から、Linuxでgccを使用してコードをテストしましたが、予想よりもはるかに堅牢です(結局、長さ0の文字バッファーへのデータの書き込みは未定義の動作です...クラッシュすると予想されます) 。
これがあなたのコードの私の修正です:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
p = malloc(sizeof(char)*0);
printf("Hello Enter some without spaces :\n");
scanf("%s",p);
char *q;
q = malloc(sizeof(char)*0);
printf("Hello Enter more data without spaces :\n");
scanf("%s",q);
printf("The first string is '%s'\n",p);
printf("The second string is '%s'\n",q);
}
私の最初の考えは、単一のメモリ位置にデータを読み取るだけであるという事実によって救われるかもしれないということでした-2つのバッファを使用する場合、2番目が最初を上書きする可能性があります...それでコードを入力と出力に分割しましたセクション:
Hello Enter some without spaces :
asdf
Hello Enter more data without spaces :
tutututu
The first string is 'asdf'
The second string is 'tutututu'
最初のバッファが上書きされた場合、次のようになります。
The first string is 'tutututu'
The second string is 'tutututu'
そうではありません。[ただし、これは各バッファにパックするデータの量によって異なります...以下を参照してください]
次に、クレイジーな量のデータを両方の変数に貼り付けました。
perl -e 'print "c" x 5000000 . "\n" ' | xsel -i
(これにより、4 MB以上の「c」がコピーバッファに入れられます)。これを最初と2番目のscanf呼び出しの両方に貼り付けました。プログラムは、セグメンテーション違反なしでそれを取りました。
セグメンテーション違反はありませんでしたが、最初のバッファが上書きされました。大量のデータが画面に表示されたため、わかりませんでした。データが少ない実行は次のとおりです。
$ ./foo
Hello Enter some without spaces :
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Hello Enter more data without spaces :
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
The first string is 'aaaaaaaaaaaa'
The second string is 'ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc'
aaaaaaaaaaaaの後に小さなグリフがありました。これは、私の端末が表示できないユニコード文字を表す方法です。これは、上書きされたデータの典型的な例です。データを上書きする内容がわからない...未定義の動作であるため、鼻の悪魔になりがちです。
肝心なのは、スペースを割り当てていないメモリに書き込むと(mallocを明示的に使用するか、配列を暗黙的に使用する)、火遊びをしているということです。遅かれ早かれ、あなたは記憶を上書きし、あなた自身にあらゆる種類の悲しみを引き起こします。
ここでの本当の教訓は、Cは境界チェックを行わないということです。それはあなたが所有していない記憶にあなたが喜んで書くことを可能にするでしょう。あなたは一日中それをすることができます。プログラムは正しく実行される場合と実行されない場合があります。クラッシュしたり、破損したデータを書き戻したり、テスト中に使用したバイト数より1バイト多くスキャンするまで機能する場合があります。それは気にしないので、あなたはそうしなければなりません。
の場合は、この質問malloc(0)
の特殊な場合です。