LoginSignup
5
1

More than 3 years have passed since last update.

rustのアドレス値と各要素の仕様確認

Posted at

Vec

コード

fn main() {
  let mut v: Vec<String> = vec![];

  for i in 0..5 {
    v.push("h".to_string());
  }
  println!("&v: {:p}", &v);
  println!("&v[0]: {:p}", &v[0]);
  println!("&v[1]: {:p}", &v[1]);
  println!("&v[2]: {:p}", &v[2]);
}

結果

&v: 0x7ffeebfd20a0
&v[0]: 0x7ff29bc02ce0
&v[1]: 0x7ff29bc02cf8
&v[2]: 0x7ff29bc02d10

アドレス値は16進数で表現されている。
vectorは連続したある程度のサイズのメモリを一度に確保する。
この事からStringは24byteをベースに持ち、ヒープにstringの中身のchar配列を持っててそれ分の用量を食ってる様子が伺える。
ちなみにv[0]等でStringを参照しているが、これは全て借用で借りているので、v[0]とかの所有権だけ欲しいとかはできない。どうしても欲しい場合はクローンする必要がある。

Vec

コード

fn main() {
  let mut v: Vec<i32> = vec![];

  for i in 0..5 {
    v.push(i);
  }
  println!("&v: {:p}", &v);
  println!("&v[0]: {:p}", &v[0]);
  println!("&v[1]: {:p}", &v[1]);
  println!("&v[2]: {:p}", &v[2]);
}

i32は名前の通り32ビット型の整数型である。
このコードを実行すると以下の出力を確認できる。

&v: 0x7ffeefbda0b8
&v[0]: 0x7fd791c02c60
&v[1]: 0x7fd791c02c64
&v[2]: 0x7fd791c02c68

32ビットは4バイト。ちゃんと連続で確保されている。正しい。

Vecのメモリ引っ越しの確認

引用

新規要素をベクタの終端に追加すると、ベクタが現在存在する位置に隣り合って要素を入れるだけの領域がなかった場合に、 メモリの新規確保をして古い要素を新しいスペースにコピーする。

この挙動を実際に確認します。
対象コードはこちら

fn main() {
  let mut v: Vec<i32> = vec![];

  for i in 0..5 {
    v.push(i);
  }
  println!("&v: {:p}", &v);
  println!("&v[0]: {:p}", &v[0]);
  println!("&v[1]: {:p}", &v[1]);
  println!("&v[2]: {:p}", &v[2]);

  v.push(1);

  println!("&v: {:p}", &v);
  println!("&v[0]: {:p}", &v[0]);
  println!("&v[1]: {:p}", &v[1]);
  println!("&v[2]: {:p}", &v[2]);

  for i in 0..5 {
    v.push(i);
  }

  println!("&v: {:p}", &v);
  println!("&v[0]: {:p}", &v[0]);
  println!("&v[1]: {:p}", &v[1]);
  println!("&v[2]: {:p}", &v[2]);
}

結果

&v: 0x7ffeef230dc8
&v[0]: 0x7fc53dc02c60
&v[1]: 0x7fc53dc02c64
&v[2]: 0x7fc53dc02c68
&v: 0x7ffeef230dc8
&v[0]: 0x7fc53dc02c60
&v[1]: 0x7fc53dc02c64
&v[2]: 0x7fc53dc02c68
&v: 0x7ffeef230dc8
&v[0]: 0x7fc53dc02d70
&v[1]: 0x7fc53dc02d74
&v[2]: 0x7fc53dc02d78

1つだけpushしても余分にとっていた様で、再確保されませんでしたが、追加でいくつかpushしたら再確保されましたね。
vectorのこの仕様のおかげでvector内を探索したり要素を参照するのがとても高速ですが、沢山pushしたり長さを調整すると何度も再確保され、そこにコストがかかっている様子が確認できました。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1