C++ 从函数返回将进入Visual Studio 2012的无限循环

C++ 从函数返回将进入Visual Studio 2012的无限循环,c++,visual-c++,c++11,C++,Visual C++,C++11,我试图测试各种指针速度的速度,但遇到了一个非常奇怪的问题。当分配原始指针时,它运行良好。(存在内存泄漏,但这不是问题所在。)当我使用shared_ptr运行第二个测试时,它运行fill fine,打印日志,然后当它返回时,它进入无限循环。看起来ref计数是垃圾,但我是按值做的 #include <memory> #include <vector> #include <functional> #include <iostream> #include

我试图测试各种指针速度的速度,但遇到了一个非常奇怪的问题。当分配原始指针时,它运行良好。(存在内存泄漏,但这不是问题所在。)当我使用shared_ptr运行第二个测试时,它运行fill fine,打印日志,然后当它返回时,它进入无限循环。看起来ref计数是垃圾,但我是按值做的

#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
静态常数int总计=1000000;
int*newTest(int i)
{
返回新的int(i);
}
共享测试(int i)
{
返回共享_ptr(新整数(i));
}
模板
对填充(T fn)
{
unsigned long start=GetTickCount();
向量向量机;
车辆储备(总计);
对于(int i=0;i没有无限循环,你只是不耐烦。释放所有共享的
需要时间

为了能够声称存在无限循环,您需要实际进入代码并查看一下。检查某个地方是否存在条件永远不会改变的循环。这里不是这种情况


例如,降低你的
总数
,并验证它是否真的结束了。拥有更多的循环不会神奇地在某个数字上引入无限循环,因此如果它在一个较低的数字上工作,它在一个较高的数字上工作

或者,不要分配
int
s;分配一些测试结构,在其销毁时输出
“bye”
(以及一些计数器),您将看到“post”-测试它们是否都被删除。(当然,执行IO将增加销毁时间,但重点是验证一个条件是否正在向停止循环的方向移动。)

此外,您还可以使用
返回make_shared(i)
将分配减半,而不是
新建
自己将int放入
shared_ptr
。始终使用
make_shared

最后,只有在附加了调试器的情况下,这才是缓慢的,因为它会调试内存使用情况。也就是说,验证您要删除的内容是否可以删除,是否损坏了任何内容,等等

出于对编程的热爱,使用四个空格来缩进,而不是两个空格。

如果在debug或release with debugging中运行代码,您将获得一个可用于跟踪内存错误的调试堆。发生这种情况时,释放的内存将充满调试模式,因此代码将运行得较慢。在Visual Studio中不进行调试的情况下运行代码将在不到200毫秒内结束。

请尝试执行干净的生成。该代码将对我来说工作很好。我做到了。我也尝试了释放和调试。你可能遇到了一些奇怪的限制,但是你的堆栈大小对于
TOTAL
的任何值都是可以管理的。从你下面的评论中,听起来你遇到的奇怪限制是物理内存,强制使用交换内存。好的。几分钟后它结束了。你说的对这不是一个无限循环。但是,从1043毫秒到新,再到要删除的分钟数,很难证明使用它们是正确的。这不是我所期望的结果。@Tavison:请参阅我的编辑;这只发生在附加了调试器的情况下。另外,证明使用什么?使共享也在测试集中,但我将问题裁剪为仅与问题相关的内容。我是not看到make_共享的速度快了很多,大约50%。我使用int作为对象,只对指针类型本身进行最接近的测试。谢谢。@Tavison:50%是预期的,因为它将分配减少了一半。(我个人发现50%的速度增加相当大,但还行。)但是回到问题上来,你想证明什么?你让我认为你要避免
shared\u ptr
,因为一些感知到的性能问题。如果是这样的话,这是不恰当的推理。@Tavison:如果你的代码真的删除了
newTest
中新添加的对象,那么比较就会非常困难你很现实。现在你正在衡量
new
vs
new
+
delete
——这并不公平。