1

次のコードを使用して動的 2D 配列を作成しています。

uint32_t** arrays = new uint32_t*[1000]; 
uint32_t number = take input from console ;
arrays[0] = new uint32_t[number];
number = take input from console ;
arrays[1] = new uint32_t[number];
delete arrays[0] ;
number = take input from console ;
arrays[0] = new uint32_t[number] ;

上記のコードを実行するために 64 ビットの Unix マシンを使用しています。

上記のコードでは、マシンは 2 次元配列をポイントする 64 ビット ポインターを使用しているため、コードがより多くのスペースを使用しています。

コードを変換する方法を教えてください。32ビットポインタが必要ですか? または、スペースの複雑さを解決する別の方法はありますか? 教授から求められていないので、ベクトルのベクトルを使用したくありません。

4

4 に答える 4

2

実際、コードはすでにほとんどメモリ最適化されています。

最初の行に1000個の64ビットポインタを割り当てます。それはあなたのマシンが使用するものなので、それは避けられません。ただし、これには8000バイトしかかからないため、最近の最適化に取り組む価値はほとんどありません。

次の行では、int32_t配列にスペースを動的に割り当てます。この配列は、エントリごとに4バイトしか使用しません。したがって、3000万エントリを割り当てると、120.000.000バイトかかります。このセカンダリアレイには3000万*8バイト=240.000.000バイトかかると誤解されていると思いますが、そうではありません。ポインタのみが64ビットであり、データ自体は必要なだけのスペースを占有します。

補遺:2次元配列を割り当てると、各2次エントリの長さが明らかにわからないため、実際にはより多くのメモリを浪費することを付け加えたいと思います。ソリューションは、必要なだけのスペースを割り当てます。

于 2012-12-31T14:49:56.000 に答える
1

これはおかしな考えかもしれませんが、繰り返しになりますが、あなたの質問も最も標準的なものではありません。

ヒープのベースアドレスからのオフセットだけを使用しないのはなぜですか?32ビットヒープアドレススペース(4GBヒープ)に制限されますが、64ビットポインターに必要な余分な4バイトをあきらめたくない場合は、それを克服するのに苦労するでしょう。

アイデアは、ヒープのベースアドレス(完全に単純ではない場合でも可能)をグローバル変数で取得することです-それをheap_base...またはそのようなものと呼びましょう。

ここで、ポインターを作成するときは、その値全体を最初の配列に格納せず、heap_baseからのオフセット(差)のみを格納します。
要素にアクセスする場合は、加算を使用して正しいポインタ値を復元します。

これは機能しない可能性があります-OSがヒープにデータを割り当てる方法によって異なります-しかし、私はそれが解決策の良いアイデアを与えるかもしれないと思いました。

于 2012-12-31T14:45:51.990 に答える
1

システムのポインター サイズを制御することはできません。

気にしないことを選択するか、ポインターの配列の代わりに実際の 2D 配列を使用することをお勧めします。

于 2012-12-31T13:55:09.460 に答える
0

それを見るもう1つの方法(むしろf * # @&dアップ方法)は、1つの64ビットポインターを使用して2つの32ビット数を格納することです。したがって、64 ビットの数値の配列を持ち、各要素に 2 つの 32 ビットの数値を格納します。

そして、ビット操作やその他の方法を使用して、これらに 32 ビット値としてアクセスするための別のメソッドを記述します。たとえば、get は次のようになります。


uint32_t get (int i, int j)
{
   if (j % 2 == 0) 
    {
      return array[i][j/2] % (2^32)
    }
    else
    {
      return array[i][j/2] / (2^32)
    }
};

于 2012-12-31T14:10:28.950 に答える