2014-04-20 145 views
0

我有以下问题: 我在课堂树这个方法:C++返回,而不是它全局实例变量的副本

Node * nearest(const Point & point) const{ 
    double minDistance = numeric_limits<double>::max(); 
    Node * nearest = new Node; 
    for(Node *n : nodesVector){ 
     int actualDistance = point.distance(n->point); 
     if(minDistance > actualDistance){ 
      nearest = n; 
      minDistance = actualDistance; 
     } 
    } 
    return nearest; 
} 

这种方法是从另一个类调用如下:

void extend(const Point & rand){ 
    Node *xNear = this->tree.nearest(rand); 
    Node *xRand = tree.add(rand, xNear); 
    std::vector<Node *> xNearSet = tree.rNearest(rand, this->RADIUS); 
    for(Node *node : xNearSet){ 
     double c = node->cost + node->point.distance(rand); 
     if(c < xRand->cost){ 
      xRand->parent = node; 
     } 
    } 
    for(Node *node : xNearSet){ 
     double c = xRand->cost + node->point.distance(rand); 
     if(c < node->cost){ 
      node->parent = xRand; 
     } 
    } 
} 

我需要我的方法最接近并扩展到扩展执行后不改变树中的变量,特别是最近的节点。

所以我认为使用指针会为我做这件事,但不幸的是它没有,所以我试图创建新的指针节点,但这种方法也不适合我。

我想问一下,我怎样才能实现它不改变原来的节点(只使用它的副本,将不被视为本地变量或引用原来的那个)最近使用?

非常感谢您的任何建议。

编辑: 也许我会稍微改写一下这个问题。现在,我已删除了内存泄漏,该行:

Node * nearest = new Node; 

一行:

Node * nearest = nullptr; 

但主要问题是,现在仍然是局部变量节点后* xNear消失再有奇怪的值分配给最靠近的原始节点。

+1

“最近”的代码调用'new'并覆盖存储的变量 - > MEMORY LEAK。 – laune

+1

如果你用'new()'创建类实例,你应该决定哪个类应该保存它们,或者使用[** smart pointers **](http://en.cppreference.com/w/cpp/memory)来管理内存取消/分配给你。 –

+0

以前关于内存管理的评论是关注的。现在,如果你想要一个被指向的对象的副本,那么你将不得不创建一个。 (根据定义,指针指向原始对象)。例如,如果您想处理由'nearest'返回的值的副本,则需要沿着'Node copiedNode = * x近似;' – Lilshieste

回答

0

所以最大的问题是,错误地初始化了最接近构造函数的初始值(作为一个局部变量没有新建),所以它的值被重写为一些奇怪的值。它只发生在当xNar从Node值发现最初的第一个时。

0

一旦分配了nearest = n;,最近的变量不再指向new ly创建的对象,而是指向nodesVector集合中找到的对象 - 并返回一个。

,如果你想返回一个副本,则不会改写nearestn指针,而是赋值对象指向:

*nearest = *n; 

(确保你在正确的定义赋值运算符Node类)。这样您将返回最近对象的副本。

+0

但是我不会随时修改最近的对象,但在我看来,它被当作局部变量处理,因此后来以某种方式随机重新初始化为一些非常奇怪的值。 当局部变量xNear消失时,原始变量以我想要阻止的奇怪方式修改。 – ziky90

+0

那么,你将'tree.nearest(rand)'找到的'xNear'指针传递给'tree.add'函数 - 但是你不会显示'Tree :: add'方法的实现,所以很难猜测对象是否实际上未被修改。此外,你修改了一些“父”链接......你确定你不会破坏你的“树”的内部一致性吗?我不明白,因为你没有说明什么是父母对孩子和孩子对父母的联系,你也没有解释在结构中树中保存了哪些条件(哪些可能被违反)生活。 – CiaPan

0

我想你的麻烦与你的代码中的其他操作有关。 Tree :: add()如何在你的实现中工作?树首先是如何填充的?

我的猜测是,最近的是现在在树中的两个位置,或者一个父指针指向它来自的同一个对象。

在调试器中查看您的树并导航所有指针。此外,还要打印Node的析构函数中的每个指针,以查看您是否指向可用内存。在那里设置一个断点来查找调用析构函数时退出的范围。