0

Cでのvoidポインター型キャストを理解しようとしていました。セグメンテーション違反を作成するプログラムを作成しましたが、うまくいきません。誰かが私に理由を説明できますか

コード:

#include <stdio.h>
typedef unsigned long U32; 
int main()
{
  void *obj;
  U32 value = 25;
  U32* ptr;
  printf("*(ptr)                           : %lu\n", *(ptr));
  obj = &value;
  ptr = &value;
  ptr++;  
  printf("*(U32 *)(obj)                    : %lu\n", *(U32 *)(obj)); 
  printf("*((U32 *)(obj) + 1)              : %lu\n", *((U32 *)(obj) + 1));   
  printf("*(U32 *)((U32 *)(obj) + 1)       : %lu\n", *(U32 *)((U32 *)(obj) + 1)); 
  printf("*(ptr)                           : %lu\n", *(ptr));
  return 0;
} 

出力:

*(ptr)                           : 458998657
*(U32 *)(obj)                    : 25
*((U32 *)(obj) + 1)              : 3215085752
*(U32 *)((U32 *)(obj) + 1)       : 3215085752
*(ptr)                           : 3215085752

他のすべてが初期化されていないランダムメモリを参照しているため、2番目のprintfのみが合法であり、セグメンテーション違反が発生するはずです。

4

3 に答える 3

2

UBはそのように面白いです-動作は定義されておらず、セグメンテーション違反が保証されていません。のアドレスはobj + 1、とにかくプログラムに割り当てられているスタック上の他の場所である可能性があります。ほぼ保証されたセグメンテーション違反を取得するには、obj割り当てられる前に参照を解除するだけです。

于 2012-06-15T20:36:46.663 に答える
1
 U32* ptr;
  printf("*(ptr)                           : %lu\n", *(ptr));

ptrは初期化されていないため、逆参照するのは未定義の動作です。

  obj = &value;
  ptr = &value;
  ptr++;  
  printf("*(U32 *)(obj)                    : %lu\n", *(U32 *)(obj)); 

obj有効なU32を指している限り(そして、printf形式として%luを使用している限り、U32は符号なしである必要があります)

  printf("*((U32 *)(obj) + 1)              : %lu\n", *((U32 *)(obj) + 1));   

有効な場所を過ぎて1つのU32を指すポインターを逆参照しようとしているため、未定義の動作です。

  printf("*(U32 *)((U32 *)(obj) + 1)       : %lu\n", *(U32 *)((U32 *)(obj) + 1)); 

同上。

  printf("*(ptr)                           : %lu\n", *(ptr));

をインクリメントptrしたので、有効なものを超えて1つのU32を指し、未定義の動作につながります。

あなたのコードは未定義の振る舞いを引き起こすことをするので、何が起こるかについて推論することは本当に難しく、しばしば不可能です。未定義です。予期しないことが起こる可能性があります。何か悪いことが起こる可能性があります。悪いことは何も起こり得ません、等々。Cで実行してはいけないことを実行しても、セグメンテーション違反が発生するわけではありません。

于 2012-06-15T20:42:48.743 に答える
0

ptr有効なオブジェクト(valueptr++を指しますが、オブジェクトを指しません。したがって*ptr、ポインタのインクリメント後に要素にアクセスすることは未定義の動作です。printfof*ptrはランダムなデータを表示できますが、プログラムをクラッシュさせる可能性もあります。

于 2012-06-15T20:36:16.927 に答える