Не бойтесь использовать утилиты str. man strcpy
, man strcat
. Вот что, я думаю, вы хотите (непонятно из поста):
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main()
{
char* home = getenv("HOME");
char* add = "/path.png?5667!http-get:*:image/png:!!!!!";
char* full = malloc(strlen(home) + strlen(add) + 1);
strcpy(full, home);
strcat(full, add);
printf("Full = %s", full);
return 0;
}
Я думаю, что это зависит от того, где Вы использовали бы их. Я предполагаю, что то, что Вы думаете о выполнении, является чем-то вроде этого:
template <class T>
class BinaryTreeNode
{
//public interface ignored for this example
private:
shared_ptr<BinaryTreeNode<T> > left;
shared_ptr<BinaryTreeNode<T> > right;
T data;
}
Это имело бы смысл, если Вы ожидаете, что Ваша структура данных обработает динамично созданные узлы. Однако, так как это не нормальный дизайн, я думаю, что это является несоответствующим.
Мой ответ был бы то, что не, это не соответствующее место для использования shared_ptr, поскольку использование shared_ptr подразумевает, что объект на самом деле совместно используется - однако, узел в двоичном дереве никогда не совместно используется. Однако как Martin York указал, почему изобретают велосипед - уже существует тип интеллектуального указателя, который делает то, что мы пытаемся сделать - auto_ptr. Поэтому пойдите с чем-то вроде этого:
template <class T>
class BinaryTreeNode
{
//public interface ignored for this example
private:
auto_ptr<BinaryTreeNode<T> > left;
auto_ptr<BinaryTreeNode<T> > right;
T data;
}
Если кто-либо спрашивает, почему данные не являются shared_ptr, ответ прост - если копии данных хороши для клиента библиотеки, они передают в элементе данных, и древовидный узел делает копию. Если клиент решает, что копии являются плохой идеей, то клиентский код может передать в shared_ptr, который может безопасно скопировать древовидный узел.
Поскольку левый и правый не совместно используются повышение:: shared_ptr <> является, вероятно, не корректным интеллектуальным указателем.
Это было бы хорошим местом для попытки станд.:: auto_ptr <>
Да, абсолютно.
Но будьте осторожны, если у Вас есть круговая структура данных. Если у Вас будет два объекта, оба с общим ptr друг другу, то они никогда не будут освобождаться, вручную не очищая общий ptr. Слабый ptr может использоваться в этом случае. Это, конечно, не является беспокойством с двоичным деревом.
Запись управления памятью вручную не является настолько трудной в тех счастливых случаях, где каждый объект имеет единственного владельца, который может поэтому удалить то, чем это владеет в его деструкторе.
Учитывая, что дерево по определению состоит из узлов, которые у каждого есть родитель-одиночка и поэтому очевидный кандидат на их единственного владельца, это - просто такой счастливый случай.Поздравляю!
Я думаю, что это было бы определенно стоящее* разработка такого решения в Вашем случае И также попытки shared_ptr
подход, скрывая различия полностью позади идентичного интерфейса, таким образом, Вы переключаетесь между двумя и сравниваете разницу в производительности для некоторых реалистических экспериментов. Это - единственный верный способ знать ли shared_ptr
подходит для Вашего приложения.
(* для нас, если Вы говорите нам, как это идет.)
Существует немного дополнительных издержек с shared_ptr, особенно в необходимых площадях, но если бы Ваши элементы индивидуально выделяются затем shared_ptr, было бы прекрасно.
Вам даже нужны указатели? Кажется, что Вы могли использовать boost::optional<BinaryTreeNode<T> > left, right
.
Никогда не используйте shared_ptr для узлов структуры данных. Это может привести к приостановке или задержке разрушения узла, если в какой-то момент владение было разделено. Это может привести к тому, что деструкторы будут вызываться в неправильной последовательности. Хорошей практикой в структурах данных является то, что конструкторы узлов содержат любой код, который связан с другими узлами, а деструкторы содержат код, который отделяется от других узлов. Деструкторы, вызванные в неправильной последовательности, могут нарушить эту схему.