2016-05-16 4 views
1

未初期化ローカル変数は不確定な値を持ち、未定義の動作を呼び出すことが知られています。しかし、ポインターを使用してフラグメントをコピーし、後で同等性をチェックする操作は、未定義の動作につながりますか?intのフラグメントをコピーした後の等価性チェック

次はコンパイルと実行がスムーズですが、わかりません。

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    int p; 
    int q = 1; 

    char *_p = (char *)&p; 
    char *_q = (char *)&q; 

    size_t n; 
    for(n = 0; n < sizeof(int); n++) { 
     memcpy(_q++, _p++, sizeof(char)); 
    } 

    if (p == q) { 
     printf("Equal!!!\n"); 
    } 

    return 0; 
} 
+2

ユニテール化された変数またはメモリの使用は、未定義の動作です。初期化されていないメモリからコピーしているので、そのコピーの結果を使用する操作はすべて未定義の動作です。 – kaylum

答えて

1

あなたは初期化メモリを超える未初期化のメモリをコピーしています。最終的な結果は、両方のメモリ位置の内容が同一であり、したがって一致することである。ソースが初期化されていないので、その価値は保証されません。この値を以前に初期化した値にコピーすると、その値が設定されている値がすべて消去され、未知の値に置き換えられます。

したがって、これらは一致します。

コピー・ルーチンが少し過大ですが、私はあなたがそれを認識していると想像して、純粋に実験のためにそれを使用して:)

+1

"初期化されていないメモリ上で初期化されたメモリをコピーする"。それは別の方法です。 OPは初期化されていないメモリからコピーしています。それは未定義の振る舞いです。 – kaylum

+0

はい、コピーは逆です。ただし、両方の整数値(定義されていませんが)は互いに正確に一致して一致するため、結果は未定義になりません。 – Graeme

+0

それは間違っています。コンパイラはUBに遭遇すると、好きなことを何でもすることができます。値は同じである可能性が高いですが、実装がその結果を毎回与えるという要件または保証がないため、依然としてUBです。 – kaylum

0

を@ジョナサンをフォローアップするためには、未定義の動作が、未定義の値を扱っていません。未定義の値はうまくコピーされます。

未定義の値で除算するなどの操作を実行しようとすると、何が未定義になりますか(ゼロかもしれません)。あるいは、未定義のポインタを介して値を代入する。

 
    int *p; 
    int q = 1; 

    char *p = q; 

以降を試してみて、あなたがいない場合、あなたは非常によく、セグメントの障害、および、おそらくいくつかのランダムメモリ位置をオーバー歩いていること。小規模で短命のプログラムでは気づかれませんが、大規模で長命のプログラムにとっては恐ろしい問題です。

コンパイラのチェックを積極的にオンにすると、単純なケースが発生する可能性があります。より明白でないケースでは、深刻なデバッグの問題が発生します。