2012-03-22 2 views
1

ESContextという名前の構造体の定義を持つヘッダーファイルesUtil.hがあり、そのメンバーの1つがuserDataです。 userDataはvoidへのポインタです。これはポインタですか? (もしそうなら、それはどのように初期化されましたか?)

それを使用してプログラムの本体は簡単に、このです:

#include "esUtil.h" 

typedef struct { 
GLuint programObject; 
} UserData; 

int DoSomething(ESContext *esContext) { 
UserData *userData = esContext->userData; 

... 
} 

int main(int argc, char *argv[]) { 
ESContext esContext; 
UserData userData; 

esStart(&esContext); 
esContext.userData = &userData; 

... 
if(!DoSomething(&esContext)) 
    return 0; 

... 
} 

私は "のuserDataは*" 文であるものによって混乱している:UserDataの*のuserData = esContext->のuserData。

ポインタであれば、宣言されずにどのようになったのか。説明をありがとう。

+4

それは宣言され、右が初期化されています。どうしたの? –

+1

"userdata"が表示されます* 2回* - またはその場合は3回無視します。 *どちらがあなたを混乱させていますか? –

+0

同じステートメントでポインタを宣言して使用することができるかどうか、それが実際に=の左側に何が起こっていたのかを知りたいだけでした。ありがとう。 –

答えて

6

はい、ポインタです。ライン

UserData *userData = esContext->userData; 

UserData *UserDataへのポインタ)とuserDataと呼ばれる変数を宣言し、値esContext->userDataでそれを初期化します。

1

ここで、ESContextのメンバーuserDataはUserData構造体で初期化され、DoSomething関数のUserDataポインターに割り当てられる理由があります。

これは、ボイドポインタかもしれないが、まだそれはUserDataのオブジェクト

1

userDataのアドレスが実際にポインタで保持しているかもしれません。これはポインタ型(型名の中の星型はチップオフです)として宣言されています。このコードはおそらくコンパイルされるため、ポインタ型でなければなりません。 userData(メイン)の取引を投稿していないコードがない場合は、yes userDataは初期化されていません。

あなたは「初期化されないとどのようになったのか」と尋ねます。さて、主流のC/C++実装では、ポインタはシステム上のワードサイズ(32ビットシステムでは32ビット、64ビットシステムでは64ビット)と等しいサイズの整数です。ポインタを逆参照すると、CPUはポインタが表すアドレスに移動し、関連するデータを取得します。データがなければ、あなたのプログラムはあなたが運が良ければkaboom(on * nix、segfaults)に行き、そうでないなら奇妙なことをします。この場合、メインのuserDataが宣言されているので、データは実際にそこにあります。しかし、初期化されていないので、userDataの内容は何でもかまいません。 DoSomethinguserDataのコンテンツを使用していない限り、そのアドレスを操作しているだけなので問題ありません。しかし、userDataを逆参照しようとすると、CPUはメモリに出てゴミを引いてしまいます.の中でどのビットパターンも可能なので、プログラムはあらゆる種類の奇妙なことを行うことができます。userDataの計算はすべての種類の異なる結果。

C/C++言語仕様は初期化されていない値を使用すると、コンパイラは、ハードドライブを消去、またはカーニハンとリッチーに脅かすメッセージを送信、または実行するコードを挿入することができることを意味し、本当に未定義である、未定義の動作を与えることを言います初期化されていない値を使用するたびに好きなもの。しかし、実際のコンパイラが生成するコードは、ガベージビットパターン(通常、以前の関数呼び出しからのスタックデータを残します)を提供します。だから、初期化されていない値を使用してが間違っている、それはあなたを殺すことはありません。

初期化されていない値と悪いポインタに関するこの奇妙なことのすべては、CおよびC++が安全でない言語である最も目立つ方法の1つです。 Eric LippertはCとC++が安全でない別の方法を説明していますhere

+2

悲しいことに、脅迫状はリッチーに届く可能性は低いです。 –

1

それはポインタであり、それは、この行で初期化されます:

esContext.userData = &userData; 
関連する問題