2017-01-04 6 views
1

私はいくつかのコードを書いていましたが、私は関数callocを使いました。callocに関する奇妙なこと

私は、この関数に渡される最初と2番目の引数が両方ともゼロである場合、関数は0個の要素に必要なスペースを割り当てようとしていることを理解しています。

このプログラムは、n> 0であっても正常に動作します。どうしてですか?存在しない配列の位置に書き込もうとしているので、エラーが表示されるはずです。ありがとう!

#include <stdio.h> 
#include <stdlib.h> 

int main(){ 
    int n; 
    scanf("%d", &n); 
    int *test = calloc(0, 0); 
    for(int i = 0; i < n; i++){ 
    test[i] = 100; 
    printf("%d ", test[i]); 
    } 
    return 0; 
} 
+6

未定義の動作は何かが起こる可能性があることを意味します。 – Kevin

+1

構文エラーなし= 'c'にコンパイルエラーがありません。あなたがコンパイルしたものはうまくコンパイルされていますが、未定義の動作である( 'n> 0'のとき)あなたのメモリ領域を越えて書くことになります。 – yano

+1

cのようなエラーはありません。それは指定されたアドレスに試してみるだけです。プログラマは、それが起こらないように注意しなければなりません。 –

答えて

0

Cでは、多くの間違った「間違った」ことは、コンパイラからのエラーメッセージを表示しません。実際には、プログラムを実行するとエラーメッセージが表示されないこともありますが、別のコンピュータでプログラムを実行している別のユーザーがエラーを表示することがあります。

Cの重要な概念の1つは、という未定義の動作と呼ばれています。簡単な言葉で言えば、プログラムの動作が予測できないことを意味しますが、この問題の詳細はUndefined, unspecified and implementation-defined behaviorで読むことができます。

あなたのプログラムは、二つの理由のために定義されていない:

  1. sizeまたはnmembのどちらかがゼロである、calloc()NULLを返すことがあります。あなたのプログラムはcalloc()の出力をチェックしていないので、test[i]を実行したときにNULLポインタを逆参照しようとしている可能性があります。calloc()malloc()の結果を常に確認する必要があります。
  2. malloc()またはcalloc()を呼び出すときは、配列にダイナミックメモリを割り当てることが重要です。ポインタを使用して配列の要素にアクセスできます。しかし、配列を最後ににアクセスすることはできません。つまり、n要素を割り当てる場合は、n+1番目の要素にアクセスしないでください。

上記の両方の項目は、プログラムが未定義の動作を呼び出すようにします。 も上記の項目#2以外の空のオブジェクトにアクセスすることについては未定義ですが、わかりません。

プログラムがUBを呼び出すときには、が予期しないであるため、未定義の動作に注意する必要があります。あなたは、何の問題もなくsuccessfulyエラーmessagen、それはでし実行を与える可能性がプログラムをコンパイル・エラーを見ることができたか、それはあなたのハードディスク内のすべての単一のファイルを一掃できました。

関連する問題