2

さまざまなポインター速度の速度をテストしようとしていますが、非常に奇妙な問題に遭遇しました。生のポインターを割り当てると、正常に実行されます。(メモリ リークがありますが、それは問題ではありません。) shared_ptr を使用して 2 番目のテストを実行すると、fill が正常に実行され、ログが出力され、返されると無限ループに入ります。参照カウントがガベージのように見えますが、私はすべてを値で行っています。

#include <memory>
#include <vector>
#include <functional>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>

#include <Windows.h>

using namespace std;

static const int TOTAL = 1000000;

int* newTest(int i)
{
  return new int(i);
}

shared_ptr<int> sharedTest(int i)
{
  return shared_ptr<int>(new int(i));
}

template <typename T>
pair<int, vector<typename T::result_type>> Fill(T fn)
{
  unsigned long start = GetTickCount();
  vector<typename T::result_type> vec;
  vec.reserve(TOTAL);
  for(int i = 0; i < TOTAL; i++)
  {
    vec.push_back(fn(i));
  }
  unsigned long end = GetTickCount();
  return make_pair(end - start, move(vec));
}

template <typename T>
void Test(T fn, string name)
{
  vector<typename T::result_type> newTest;
  int milliseconds = 0;
  tie(milliseconds, newTest) = Fill(fn);
  cout << "Fill " << name << " Took " << milliseconds << " milliseconds." << endl;
}

int main()
{
  function<int*(int)> fn1 = newTest;
  Test(fn1, "Raw Ptr");

  function<shared_ptr<int>(int)> fn2 = sharedTest;
  Test(fn2, "Shared New");

  return 0;
}

わかった。Stackoverflow でスタック オーバーフローの質問をしたようです... TOTAL を 10000 に設定すると問題ありません。それで、それは他の何かの症状ですか、それともスタックサイズを増やす必要がありますか?

コメントから編集:

タビソン: わかりました。数分後、終了しました。あなたは無限ループではないことについて正しいです。ただし、新規作成には 1043 ミリ秒、削除には数分かかるため、それらの使用を正当化するのは困難です。これは私が期待する結果ではありません。

4

2 に答える 2

6

無限ループはありません。せっかちなだけです。すべての を解放するのに時間がかかっていshared_ptrます。

無限ループがあると主張できるようにするには、実際にコードに足を踏み入れて調べる必要があります。決して変わらない条件のループがどこかにあることを確認してください。ここではそうではありません。


たとえばTOTAL、を下げて、実際に終了することを確認します。これらの数を増やしても、ある数で魔法のように無限ループが発生するわけではないため、低い数で機能する場合は、高い数で機能します。

intまたは、 sを割り当てないでください。"bye"破壊時に(いくつかのカウンターとともに)出力するいくつかのテスト構造体を割り当てると、それらがすべて削除されていることを「ポスト」テストで確認できます。(もちろん、IO を実行すると破棄時間が長くなりますが、ポイントは、条件がループを停止する方向に進んでいることを確認することです。)

また、自分で int を ing しreturn make_shared<int>(i);て. 常に使用します。newshared_ptrmake_shared

最後に、これはデバッガーが接続されている場合にのみ遅くなります。これは、メモリ使用量をデバッグするためです。つまり、削除しようとしているものが削除しても問題がないこと、何も破損していないことなどを確認してください。

また、プログラミングが好きな方は、インデントに 2 つではなく 4 つのスペースを使用してください。

于 2013-03-29T20:01:46.190 に答える
4

コードをデバッグで実行するか、デバッグを使用してリリースすると、メモリ エラーの追跡に使用できるデバッグ ヒープが得られます。これが発生すると、解放されたメモリがデバッグ パターンでいっぱいになるため、コードの実行が遅くなります。Visual Studio からデバッグせずにコードを実行すると、200 ミリ秒未満で終了します。

于 2013-03-29T20:13:57.987 に答える