Область указателя в C ++ - PullRequest
0 голосов
/ 16 марта 2011

Хотя это очень общий вопрос, вот мой конкретный пример, чтобы вы могли понять, о чем я спрашиваю.

У меня есть конструктор копирования для класса четырехугольников.Поэтому я пишу рекурсивный вспомогательный метод с именем copy, чтобы я мог вызывать его в своем конструкторе копирования.Помощник принимает один параметр, узел.Корневой узел задается в качестве первого аргумента при вызове из конструктора.

Так что теперь в моем вспомогательном методе я создаю один новый узел с именем newNode, и у каждого узла есть переменные-члены neChild, nwChild, seChild, swChild ---- sw означает юго-запад nw, ne, se - все кардинальные направления, и я устанавливаю каждый новый дочерний элемент равным таковому в source.child.Затем я снова вызываю вспомогательный метод для каждого source.child (4 из них).Таким образом, 1 узел становится 4, который имеет 16 дочерних элементов и т. Д.И тогда я возвращаю тот первый newNode, который я создал.

Вопрос:

Будут ли к этому новому возвращенному узлу присоединены все остальные узлы?Будет ли это в древовидной структуре (хотя формально не в дереве)?Или эти указатели, прикрепленные к возвращенным указателям, выйдут из области видимости?

Ответы [ 5 ]

1 голос
/ 16 марта 2011

В результате вы получите новый корневой узел, который связан с теми же дочерними узлами, что и исходное дерево. Таким образом, любые изменения, внесенные в любые дочерние элементы, затронут оба дерева, и у вас может возникнуть проблема с двойным освобождением позже.

Это потому, что, хотя вы и вызываете copy рекурсивно, вы отбрасываете возвращаемое значение.

Кроме того, вы сказали, что эта copy функция вызывается из вашего конструктора копирования? Вас ждет мир боли, потому что copy вызывает конструктор копирования (в операторе return, поскольку вы возвращаете по значению). Это рецепт для ПЕРСПЕКТИВЫ. Я думаю, вы находитесь в правильном месте;)

1 голос
/ 16 марта 2011

Во-первых, как уже отмечали другие, вы путаете QuadtreeNode и QuadtreeNode* при создании newNode.Я предполагаю, что это указатель.

Во-вторых, вы недостаточно хорошо защищаетесь от NULL.

В-третьих, если мое чтение этого кода правильное, четыре рекурсивных вызова copy не производит ничего, кроме утечек памяти;каждый вызов генерирует новый узел в куче и возвращает указатель на этот новый узел, но ваш код не сохраняет этот указатель.Так что copy вернет указатель на новый узел, у которого есть дочерние указатели, указывающие на потомков аргумента узла - и все.

0 голосов
/ 16 марта 2011

Если вы возвращаете QuadtreeNode* из вашего метода copy, указатель, который вы возвращаете из этой функции, останется действительным вне этой функции, пока вы не освободите память вручную, используя delete.

0 голосов
/ 16 марта 2011

Если тип newNode равен QuadtreeNode*, то для доступа к переменным / методам-членам используется оператор ->.

newNode лежит в стеке, но память, на которую он указывает, лежит в куче (и в этом случае объект находится в этом случае).Таким образом, он возвращает ссылку на местоположение в куче (если тип возвращаемого значения QuadtreeNode*).Все в порядке.Но программе необходимо освободить ресурсы, полученные из кучи / свободного хранилища, используя delete, иначе утечка памяти преобладает.

0 голосов
/ 16 марта 2011

Материал, выделенный из кучи , не будет выходить за рамки при возврате функции.Локальная переменная , указывающая на что-то в куче, вышла бы из области видимости, но, если вы возвращаете ее из функции, то вы сохраняете копию.

Если, однако,эти переменные являются автоматическими (в стеке), они будут выходить из области видимости при возврате.

И, основываясь на вашем коде, это было что-то вроде (без публикации фактического код с тех пор, как OP заявил, что это домашнее задание, и они не хотели сохранять копии):

XTreeNode XTreeNode::copy(XTreeNode & const n) {
    XTreeNode *newNode = new XTreeNode(7);  // <-- Note "*", this is important.
    newNode.xy=n.xy;
    return newNode;
}

Вы выбрали третий из тех двух вариантов, которые я дал: -)

Поскольку вы передаете n, он все равно будет находиться в области видимости при выходе из функции, и одна вещь, которая выходит из области видимости (newNode), в любом случае возвращается, поэтому у вас все равно будеткопия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...