-1
int main()
{
int *p,*q;
p=(int *)1000;
q=(int *)2000;
printf("%d:%d:%d",q,p,(q-p));
}

出力

2000:1000:250

1.行がわかりp=(int *)1000;ません。これは、pが1000アドレスの場所を指していることを意味しますか?*p=22この値は1000アドレスに保存され、既存の値を上書きするとどうなりますか?値を上書きする場合、別のプログラムが1000アドレス空間で動作しているとどうなりますか?

  1. どのようにq-p=250

編集:printf("%u:%u:%u",q,p,(q-p));私は出力が同じである ことを試しました

int main()
{
int *p;
int i=5;
p=&i;
printf("%u:%d",p,i);
return 0;
}

出力

3214158860:5
  1. これは、コンパイラが使用するアドレスが整数であることを意味しますか?通常の整数とアドレス整数の間に違いはありませんか?
4

6 に答える 6

4

これは、pが1000アドレスの場所を指していることを意味しますか?

はい。

* p=22を実行するとどうなりますか

これは未定義の動作を引き起こします-プログラムはおそらくセグメンテーション違反でクラッシュします。

最近のOSでは、アドレスは仮想であることに注意してください。このように他のプロセスのアドレス空間を上書きすることはできませんが、自分のプロセスのアドレス空間の無効なメモリ位置に書き込もうとすることはできます。

どのようにqp=250?

ポインタ演算はこのように機能するため(配列のインデックス付けと互換性を持たせるため)。2つのポインターの違いは、それらの値の違いを。で割ったものsizeof(*ptr)です。同様に、型nのポインタに追加すると、数値になります。ptrTptr + n * sizeof(T)

ポインタでこれを読んでください。

これは、コンパイラが使用するアドレスが整数であることを意味しますか?

その「コンパイラによって使用される」部分は必要さえありません。アドレス整数です。私たちの生活を楽にするための優れたポインターがあるのは、Cでの単なる抽象化です。アセンブリでコーディングしている場合は、それらを符号なし整数として扱うだけです。

ちなみに、書く

printf("%u:%d", p, i);

また、未定義の動作です。フォーマット指定子は、ポインターではなく、を%u予期します。unsigned intポインタを出力するには、次を使用します%p

printf("%p:%d", (void *)p, i);
于 2012-11-20T06:59:01.237 に答える
1

の意味p = (int *) 1000は実装定義です。しかし、はい、典型的な実装では、pアドレスを指すようになります1000

後で行うと、実際にアドレス*p = 22に保存しようとします。ただし、通常、この試みは未定義の動作につながります。これは、任意のメモリ位置にデータを書き込むことだけが許可されていないためです。メモリを使用できるようにするには、何らかの方法でメモリを割り当てる必要があります。あなたの例では、アドレスに何も割り当てる努力をしていません。これは、適切に割り当てられていないメモリ領域にデータを書き込もうとしたため、プログラムが単にクラッシュする可能性が高いことを意味します。(さらに、多くのプラットフォームでは、ポインターを介してデータにアクセスするために、これらのポインターは適切に配置された場所を指している必要があります。)2210001000

22どういうわけか自分の住所を書くことに成功したとしても1000、それが「他のプログラム」に何らかの影響を与えるという意味ではありません。一部の古いプラットフォームでは、そうなります(DOSのように、1つの例から)。しかし、最新のプラットフォームは、実行中のプログラム(プロセス)ごとに独立した仮想メモリを実装しています。これは、実行中の各プロセスが独自の個別のアドレス1000を持ち、他のプログラムのアドレスを認識できないことを意味します1000

于 2012-11-20T07:10:40.703 に答える
1

はい、*p=221000アドレスに書き込みます。

q-pintのサイズが4であるため、250になります。したがって、2000-1000 / 4=250になります。

于 2012-11-20T06:59:58.927 に答える
0
  1. はい、p仮想アドレス1000を指しています。を使用する*p = 22;と、セグメンテーション違反が発生する可能性があります。多くの場合、最初の1024バイト全体が読み取りまたは書き込みに無効です。仮想メモリがあると仮定すると、別のプログラムに影響を与えることはできません。各プログラムには、独自の仮想アドレス空間があります。

  2. の値は、2つのアドレスq - pのユニット数sizeof(*p)または2sizeof(*q)sizeof(int)のアドレス間のユニット数です。

于 2012-11-20T07:01:19.563 に答える
0

任意の整数をポインタにキャストすることは未定義の動作です。何も起こらない、セグメンテーション違反、他のプロセスのメモリを黙って上書きするなど、何でも起こり得ます(最新の仮想メモリモデルではあり得ないことです)。

しかし、実際のDOS時代には、このような絶対アドレスを使用して、割り込みテーブルとBIOS変数にアクセスしていました:)

についてq-p == 250、それはポインタ演算のセマンティクスの結果です。どうやらsizeof intあなたのシステムでは4です。したがって、intポインタに1を追加すると、実際には4ずつインクリメントされるため、次のバイトではなく次のバイトを指しintます。この動作は、アレイへのアクセスに役立ちます。

于 2012-11-20T07:06:44.247 に答える
-1
does this mean that p is pointing to 1000 address location?

はい。ただし、この1000アドレスは、他のプロセスアドレスに属している可能性があります。この場合、別のプロセスのアドレス空間のメモリに不正にアクセスしています。これにより、セグメンテーション違反が発生する可能性があります。

于 2012-11-20T06:58:31.677 に答える