BST의 루트 노드를 반환하려고합니다. 내 재귀 함수는 SPnodes
(트리 노드 객체)의 컨테이너로 std::vector
을 사용하여 하나의 호출이 반복되고 더 적은 수의 요소가있는 벡터가 다음 호출로 전달됩니다. 벡터의 크기가 1이되면 내 함수는 벡터 컨테이너 인 nodeList
의 첫 번째 (그리고 유일한) 요소에서 복사 생성자를 호출하여 생성 된 새로운 SPnode
을 반환합니다.새 메모리를 할당 한 후 분할 오류가 발생했습니다.
다음은 래퍼 함수를 통해 전달 된 다음 원래 호출자에게 전달됩니다.
질문
내가 벡터 용기가 파괴되는 범위를 벗어나면, 그러나 나는 그래서이 문제의 원인이 될 수 있는지 이해하지 못하는 새로운 메모리를 할당하고 SPnodes
을 복사하고있어 이해 . 그렇다면이 원인은 무엇입니까? 내 문제는 의심 스럽지만, 수많은 질문을 통해 답을 찾지 못하는 것 같습니다.
코드
SPnode
헤더 :
#ifndef SPNODEOBJ_H
#define SPNODEOBJ_H
#include "IntervalObjects.h"
#include "IntervalObj.h"
#include "InVecObj.h"
#include "StandardLib.h"
// --- SPnode Class ------------------------------------------------------------
// SPnode (or Subpaving Node), is a node in a binary tree which contains a
// parameter "box" which is an InVec object, and a left and right child which
// are also SPnode objects. These SPnode objects are the resultant boxes from
// calling the expand method on m_box. This implementation allows for two
// important characteristics: there is a way to determine "where" a given box in
// a subpaving is by iterating over a node's left or right child, which in turn
// allows for greater efficiency; secondly, the tree structure gives a "history"
// of the subpaving, which allows for the determination of parent boxes.
class SPnode
{
private:
InVec m_box;
// left and right children of this SPnode object - note that these must be
// pointers in order to use them in the definition of the class, otherwise
// SPnode would reference itself in its definition
SPnode* m_left;
SPnode* m_right;
// a boolean sepcifying whether the SPnode m_box is in the given subpaving
bool m_inSP;
bool m_hasBeenIterated;
public:
SPnode(InVec box): m_box(box), m_left(NULL), m_right(NULL), m_inSP(true),
m_hasBeenIterated(false) {}
SPnode(const SPnode &ASP)
{
recConstructor(this, ASP);
}
void recConstructor(SPnode* const &parent, const SPnode &ASP);
void recDestructor(SPnode* const &ASP);
~SPnode() {delete m_left;
delete m_right;}
// getters and setters
InVec getBox() const {return m_box;}
SPnode* getLeft() const {return m_left;}
SPnode* getRight() const {return m_right;}
bool getInSP() const {return m_inSP;}
bool getIterated() const {return m_hasBeenIterated;}
void setBox(const InVec box) {m_box = box;}
void setLeft(SPnode* const p_node) {m_left = p_node;}
void setRight(SPnode* const p_node) {m_right = p_node;}
void setInSP(bool truth) {m_inSP = truth;} // when this is called truth
// should only be false
void setIterated(bool truth) {m_hasBeenIterated = truth;}
bool isLeaf() const;
friend std::ostream& operator<< (std::ostream &out, const SPnode &ASP);
SPnode operator=(const SPnode& ASP)
{
std::cout << "assignment called\n";
if (this == &ASP) return *this;
recConstructor(this, ASP);
return *this;
}
friend void expand(SPnode &ASP);
friend InVec lower(const InVec &box, const Interval &width, int axis);
friend InVec upper(const InVec &box, const Interval &width, int axis);
friend void mince(SPnode &ASP);
friend SPnode regularize(ImList &list, InVec box);
friend SPnode* recRegularize(std::vector<InVec> &list, SPnode &parentNode);
};
#endif
SPnode
CPP 파일 :
#include "SPnodeObj.h"
void SPnode::recConstructor(SPnode* const &parent, const SPnode &ASP)
{
parent->m_box = ASP.m_box;
parent->m_inSP = ASP.m_inSP;
parent->m_hasBeenIterated = ASP.m_hasBeenIterated;
if (ASP.isLeaf())
{
parent->m_left = NULL;
parent->m_right = NULL;
return;
}
if (ASP.m_left == NULL)
{
parent->m_left = NULL;
}
if (ASP.m_right == NULL)
{
parent->m_right = NULL;
}
if (ASP.m_left != NULL)
{
parent->m_left = new SPnode((ASP.m_left)->m_box);
}
if (ASP.m_right != NULL)
{
parent->m_right = new SPnode((ASP.m_right)->m_box);
}
if (ASP.m_left != NULL)
{
recConstructor(parent->m_left, *(ASP.m_left));
}
if (ASP.m_right != NULL)
{
recConstructor(parent->m_right, *(ASP.m_right));
}
}
bool SPnode::isLeaf() const
{
return (m_left == NULL && m_right == NULL);
}
std::ostream& operator<< (std::ostream &out, const SPnode &ASP)
{
if (ASP.m_right == NULL && ASP.m_left != NULL)
{
out << "SPnode(SPnode, " << ASP.m_box << ", NULL)";
}
else if (ASP.m_left == NULL && ASP.m_right != NULL)
{
out << "SPnode(NULL, " << ASP.m_box << ", SPnode)";
}
else if (ASP.m_left == NULL && ASP.m_right == NULL)
{
out << "SPnode(NULL, " << ASP.m_box << ", NULL)";
}
else
{
out << "SPnode(SPnode, " << ASP.m_box << ", SPnode)";
}
return out;
}
내 기능 :
SPnode* listToTree (std::vector<InVec> boxList)
{
int counter = 0;
std::vector<SPnode> nodeList;
for (auto box : boxList)
{
nodeList.push_back(SPnode(box));
counter += 1;
}
//return recListToTree(nodeList);
//return new SPnode(*(recListToTree(nodeList)));
return recListToTree(nodeList);
}
SPnode* recListToTree (std::vector<SPnode> &nodeList)
{
std::cout << "nodelist size is: " << nodeList.size() << "\n";
if (nodeList.size() == 1)
{
return new SPnode(nodeList.at(0));
}
std::vector<SPnode> parentNodeList;
int counter = 0;
for (auto node : nodeList)
{
if (node.getIterated())
{
counter += 1;
continue;
}
if (counter + 1 == nodeList.size())
{
parentNodeList.push_back(SPnode(node.getBox()));
break;
}
if (node.getBox().isAdjacent(nodeList.at(counter + 1).getBox()))
{
SPnode newNode =
SPnode(node.getBox().combine(nodeList.at(counter + 1).getBox()));
if (lessThan(node.getBox(), nodeList.at(counter + 1).getBox()))
{
newNode.setLeft (new SPnode(node));
newNode.setRight(new SPnode((nodeList.at(counter + 1))));
}
else
{
newNode.setRight(new SPnode(node));
newNode.setLeft (new SPnode((nodeList.at(counter + 1))));
}
parentNodeList.push_back(SPnode(newNode));
nodeList.at(counter).setIterated(true);
nodeList.at(counter + 1).setIterated(true);
counter += 1;
}
else
{
parentNodeList.push_back(SPnode(node.getBox()));
nodeList.at(counter + 1).setIterated(true);
counter += 1;
}
}
recListToTree(parentNodeList);
}
도움을 주시면 감사하겠습니다.
디버거로 코드를 단계별로 실행할 때 무엇을 관찰 했습니까? –
코드가 너무 많습니다. [MCVE]를 사용하여 먼저 디버그하십시오! –