9
#include <vector>
typedef std::vector<char> vc;
typedef std::vector<vc> vvc;

vvc f() {
  const int N = (1 << 15);
  return vvc(N, vc(N)); // 1 GB
}

int main () {
  vvc v; 
  v = f();
  while(true);  // Why 2GB allocated ?
  return 0;
}

clang -O2 と g++ -O2 の両方でコンパイル。同じ動作。

編集:いくつかの回答で指摘されているこのコードを修正するには、複数の方法があります。しかし、私のポイントは、このコードを理解することです。もちろん一時的なオブジェクトはありますが、セミコロンで消え、1GB のメモリがシステムに返されます。質問は、なぜそれが起こらないのかを尋ねることを意図しています。

編集 2:一時オブジェクトのデストラクタは、セミコロンの前に実際に呼び出されます。

4

5 に答える 5

2

win32、vc7でテストしました。

コードは 2Gb を割り当てます。これに変更した場合:

int main () {
  vvc v = f();
  while(true);

必要なのは 1Gb だけです。

その理由は、ベクター間のコピー操作だと思います。

v = f()- コンストラクターを呼び出します。あなたのケース - デフォルトの c'tor と copy (operator =) を空のオブジェクトに。対処には 2 Gb が必要です。

f()(vector と return の作成)の内部アクションはRVOを使用でき、対処や余分な割り当てはありません。

于 2013-06-09T09:58:08.377 に答える
1

編集:いくつかの回答で指摘されているこのコードを修正するには、複数の方法があります。しかし、私のポイントは、このコードを理解することです。もちろん一時的なオブジェクトはありますが、セミコロンで消え、1GB のメモリがシステムに返されます。質問は、なぜそれが起こらないのかを尋ねることを意図しています。

Windows では、テストを gcc でコンパイルして実行しました。そしてPrivate Bytes、プログラムの開始後に の値が増加し、その後減少し始め、最後に変化しなくなることがわかります。したがって、この OS ではメモリがシステムに返されます。ちなみに私は を利用して のProcess Explorer情報を取得しましPrivate Bytesた。

Linux でテストを行ったとしますが、この OS ではメモリがシステムに返されません。それが使用されていない場合、私が正しければ、最終的にページング領域に移動されます。

于 2013-06-09T11:25:59.213 に答える
0

戻り値がコピーされると思います。vvc の一時的な 2 つのコピーよりも存在します。それぞれ 2^30 文字 (= 1GB)

私の知る限り、コンパイラは許可されていますが、コピー操作を削除する必要はありません

このリンクを見つけました http://en.wikipedia.org/wiki/Return_value_optimization

于 2013-06-09T10:02:27.870 に答える