2016-05-28 33 views
-4

次のコードスニペットは、64ビットのUbuntu 14.04で実行され、32ビットのUbuntu 14.04ではsegフォルトが実行されます。 gccのバージョンの両方4.8.4に同じで(Ubuntuの4.8.4-2ubuntu1〜14.04)32ビットと64ビットの動作の差

#include<stdio.h> 
main() 

{ 

    int* a; 
    int* b; 
    *a = 40; 
    b=a; 
    printf ("%x ............. %p ...........%d \n",*a,a, *a); 
} 

2のいずれかが行われた場合、同じことが、32ビットシステム上で動作します - アウト

  1. コメントb = a
  2. * a = 40より前にa=malloc (sizeof(int));を追加します。

は、誰かがこの観測それは、64ビット対32ビットの問題ではありません

+5

[tuple_catさんと@Weatherベーンのフィードバック@、Antの@統合することで編集]。あなたは 'a'に有効なメモリアドレスを割り当てていないので、ランダムなアドレスを持っています。ランダムなメモリに40の書き込みを割り当てて、何かが起こるようにするために参照解除します。 'malloc'はエラーを修正しますが、' free(a) 'を呼び出さなければメモリアドレスを持っています。 'a'を' b'に代入しても、この動作は変わりません。 –

+2

コンパイラの警告を有効にします:*警告C4700:初期化されていないローカル変数 'a'が使用されました* –

+0

** 2 **を追加しないと、未割り当てのメモリに書き込もうとしているため*未定義の動作*です。 ** 1 **はどこでも 'b'を使用していないので何も変更しません。 – Haris

答えて

2

が、有効なメモリアドレスを指していないポインタを使用しての問題を説明していただけます。コードスニペットでは、ポインタ*a*bを実際にどこにでも指定しないで宣言しているため、未定義の動作が発生します。

ポインタを使用する場合、常にすぐに適切なメモリを割り当てるか、既存の対応する変数を指すようにします。例えば

、すべての後続の文が有効である:

int *a = NULL; 
int *b = malloc(sizeof(int)); 
int c = 42; 
int *d = &c; 

それらを初期化しないことで、彼らは任意の場所を指しています。 *a = 40;はおそらく、あなたが当時のアクセス権を持っていたメモリ空間を指していた可能性があるため、あなたのために「偶然」働いていたでしょう。しかし、一般的なケースでは、このスニペットはどちらのオペレーティングシステムでもセグメンテーションエラーを生成するはずです。あなたが有効なメモリアドレスに即座にポインタを指すように計画されていない場合は

は、ダングリングポインタを避けるために、NULLにそれを初期化することを検討してください。 NULLポインターを決して参照しないでください。ただし、ポインターがNULLであるかどうかを確認する前に確認してください。たとえば:*a*b両方がNULLになるよう

int *a = NULL; 
if (a != NULL) { 
    *a = 42; 
} 
int *b = a; 
if (b != NULL) { 
    printf("%d\n", *b); 
} 

このスニペットは、何も表示されませんが、あなたのコードは、セグメンテーションフォールトを生成しません。

私はDebianの64ビットシステム上でセグメンテーションフォルトを得ています。

元のコードは未定義の動作をしている

+3

ダイナミックメモリとは何か関係がありません。あなたは 'int c; int * a =&c; 'を呼び出し、有効な' a'と '* a'を取得します。ダイナミック*メモリをここに含める必要はありません。 「ポインタ」の概念は、動的メモリに結び付けられていません。 – AnT

+3

また、 'malloc'は' void * 'を返します。キャスティングは不要です(http://stackoverflow.com/q/605845/3425536)。 – emlai

+0

@AnTフィードバックをいただきありがとうございます。私は答えをより汎用的にするために統合しました。ポインタを使用する場合、ポインタはどこか有効である必要があります。 – Adama

関連する問題