したがって、私はC ++とそれに付随するすべてのメモリ管理にかなり慣れていません。
私の問題は、関数expandでオブジェクトを作成してから、そのオブジェクトを同じクラスの別のオブジェクトのメンバー変数に割り当てることです(クラスは、データがInVecオブジェクトであるバイナリツリーです)。
関数実行後のメモリ位置m_leftとm_right所与のためSPnodeは、しかし逆参照値がジャンクであり、同じです。
私は、これはに起因することはほぼ確実だInVecとSPnodeは、スコープの外に行くと破壊されるオブジェクトを、このように得ポインタがm_leftとm_rightジャンクを指して。
私の質問は、関数内にオブジェクトを作成し、それをメンバー変数に割り当て、関数の終了時にオブジェクトを破棄しないようにするにはどうすればよいですか?明らかな何かが欠けていることは確かですが、どこにも答えを見つけることができませんでした(それをどのように表現するかさえわかりません)。
これが私のコードです:
void expand(SPnode &ASP)
{
if (!(ASP.isLeaf())) return;
int axis(ASP.m_box.getWidthAxis());
Interval width(ASP.m_box.getWidth());
InVec lowerInVec(lower(ASP.m_box, width, axis));
InVec upperInVec(upper(ASP.m_box, width, axis));
SPnode leftChild(lowerInVec);
std::cout << &leftChild << "\n";
SPnode rightChild(upperInVec);
std::cout << &rightChild << "\n";
ASP.m_left = &leftChild;
std::cout << (ASP.m_left) << "\n";
ASP.m_right = &rightChild;
std::cout << (ASP.m_right) << "\n";
}
このコードが不適切な形式である場合、またはいくつかの重要なルールに違反している場合は、お詫び申し上げます。建設的な批判もいただければ幸いです。
編集:以下は、Interval、InVec、およびSPnodeに関連するコードです。
// The Interval class is the base object on which all other classes in this
// module are built. Its implementation is intuitive, as all mathematical
// operations that are relevant for nonlinear image computation are given
// as overloaded operators (i.e. intervalA + intervalB returns the expected
// result from basic interval arithmetic).
class Interval
{
private:
// infimum (lower bound) of interval
double m_inf;
//supremum (upper bound) of interval
double m_sup;
public:
Interval(double inf, double sup): m_inf(inf), m_sup(sup) {}
// getter member functions, where getLen returns the length of the interval
// and getMidpt returns the midpoint
double getInf() const {return m_inf;}
double getSup() const {return m_sup;}
double getLen() const {return m_sup - m_inf;}
double getMidpt() const {return (m_inf + m_sup)/2.0;}
// --- Headers -----------------------------------------------------------------
// determines if a double is in the interval
bool containsVal(double val) const;
// determines if another interval is contained in the interval
bool contains(const Interval &other) const;
// performs scalar multiplication on the interval
Interval scalarMul(double scal) const;
// operator overloading - the specifics of interval arithmetic can be found
// in a book or online
friend Interval operator+(const Interval &intA, const Interval &intB);
friend Interval operator-(const Interval &intA, const Interval &intB);
friend Interval operator*(const Interval &intA, const Interval &intB);
friend bool operator==(const Interval &intA, const Interval &intB);
friend bool operator!=(const Interval &intA, const Interval &intB);
friend std::ostream& operator<< (std::ostream &out, const Interval &intA);
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);
};
class InVec
{
private:
// this is a vector containing the Interval objects that make up the InVec
// object
std::vector<Interval> m_intervals;
public:
InVec(std::vector<Interval> intervals): m_intervals(intervals) {}
// returns m_intervals
std::vector<Interval> getIntervals() const {return m_intervals;}
// returns the interval at given axis (i.e. index) in m_intervals
Interval getInterval(int axis) const {return m_intervals.at(axis);}
// sets the interval at given axis to given Interval object
void setInterval(int axis, const Interval &intA)
{m_intervals.at(axis) = intA;}
// --- Headers -----------------------------------------------------------------
// determines if another InVec object is contained in this InVec object
bool contains(const InVec &IVB) const;
// returns the length of the largest Interval object in m_intervals - note
// that it is necessary to compute this first, before the actual largest
// Interval can be determined
double getWidthSize() const;
// returns the Interval in m_intervals with the longest length
// (i.e. the width)
Interval getWidth() const;
// returns the axis (i.e. index) on which the width occurs
double getWidthAxis() const;
// operator overloading
friend InVec operator+(const InVec &IVA, const InVec &IVB);
friend InVec operator-(const InVec &IVA, const InVec &IVB);
friend InVec operator*(const InVec &IVA, const InVec &IVB);
friend bool operator==(const InVec &intA, const InVec &intB);
friend bool operator!=(const InVec &intA, const InVec &intB);
friend std::ostream& operator<< (std::ostream &out, const InVec &IVA);
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);
};
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 have an inifinite definition
SPnode* m_left;
SPnode* m_right;
public:
SPnode(InVec box): m_box(box), m_left(NULL), m_right(NULL) {}
// getters and setters
InVec getBox() const {return m_box;}
SPnode* getLeft() const {return m_left;}
SPnode* getRight() const {return m_right;}
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;}
bool isLeaf() const;
friend std::ostream& operator<< (std::ostream &out, const SPnode &ASP);
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);
};
子をポインタとして作成し、new演算子を使用して、次のように動的に割り当てる必要があります。
SPnode * leftChild = new SPnode(lowerInVec);
そして、次のようにオブジェクトメンバー変数に割り当てます。
ASP.m_left = leftChild;
また、次のように、m_leftをSPnodeポインタとして宣言する必要があります。
SPNode * m_left;
正しいものにも同じことをします。
追伸:スマートポインタを理解する前に、new演算子を使用して割り当てられるポインタを理解する必要があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加