2016-12-13 3 views
0

オクツリーデータ構造を構築し、最後のノードのためにメモリを節約する8個の子供を保持するように作られたオブジェクトを作成する代わりに、ポインタを直接値に格納したい。ポインタに符号なし整数を格納する

私のデータ型はuint32_tです。これは、ポインタがx86またはamd64のいずれかに保持するのに十分なビット数を持つことを意味します。

したがって、符号なし32ビット整数をx86またはamd64ポインタに格納するにはどうすればよいですか?

擬似コード:

uint32_t i = 123; 
Octree* ptr = i; 
uint32_t ii = ptr; 
std::cout << ii << std::endl; //Prints 123 

どのようにこれは可能ですか?可搬性ポインタが許可されていない符号なし整数でストレートを保存

+0

uint32_t i = 123; Octree * ptr = reinterpret_cast (i); uint32_t ii = reinterpret_cast (ptr); – FamZ

+0

@FamZ:x86上で動作するはずですが、技術的に違法で、クラッシュを引き起こすようないくつかの奇妙なプラットフォームがあります(これらのCPU上で無効なポインタがハードウェア例外を引き起こす* –

答えて

5

が、次のことができます。

  • 逆の操作を行います。あなたは、符号なし整数であなたのポインタを格納することができます。具体的には、uintptr_tは、標準によって明示的に保証されています。
  • 使用union

    union NodePtr { 
        Octree *child; 
        uint32_t value; 
    } 
    
    ここ

    childvalue共有し、同じメモリ位置、そしてあなたは、あなたが最後に書いたものからのみ読み取ることが許可されています。ターミナルノードにいるときはvalueを使用し、それ以外の場合はchildを使用します。

+0

共用体を使用するオーバーヘッドはありますか?上記の組合は生のポインタと同じスペースを取るでしょうか? – KaareZ

+0

@KaareZ: 'union'sは、まともな実装では事実上無料です。複数の型を持つメモリにアクセスしようとしていることをコンパイラに伝えるだけです。ユニオンのサイズは「データメンバのうち最大のものを格納するのに十分です」(実際には、最大のメンバと同じ大きさです)。 –

+0

さて、それは非常に素晴らしい解決策です。ありがとうございました。 – KaareZ

0

さて、あなたはキャストとポインタとしてint型保存することができます:

uint32_t i = 123; 
Octree* ptr = reinterpret_cast<Octree*>(i); 
uint32_t ii = reinterpret_cast<uint32_t>(ptr); 
std::cout << ii << std::endl; //Prints 123 

をしかし、あなたはそれを行う場合、私はあなたが与えられた八分木*ことを検出する方法を見ることができないこの方法は、実際にデータを格納し、他のOctreeへのポインタではありません

+0

私はそのためのboolフラグを持っています。 – KaareZ

+0

上記のように、これはx86や他の一般的なアーキテクチャでは機能しますが、技術的にはポータブルではありません(ポインタはトラップ表現を持つことができます)。 –

関連する問題