Не уверен, как вы извлекаете значения, так как вы не показали фактический запрос, который дает ожидаемый результат.
Этот запрос, кажется, работает нормально, то есть он дает то, что вы хотели изначально.
select t2.id,t2.dt,coalesce(t1.value,t2.value) as value
from t2 LEFT JOIN t1 ON
to_char(t1.dt,'yyyymm') = to_char(t2.dt,'yyyymm') and
t1.id = t2.id
ORDER BY id,dt
Если вы добавите DISTINCT
, вы получите одну запись на комбинацию id,month
, если хотите удалить дубликаты. Вы также можете сделать group by id
или все, что хотите, чтобы получить агрегацию
. Обратите внимание, что ниже приводится только если вы хотите предпочесть значение таблицы 1 над таблицей 2, иначе достаточно просто выбрать строки из t2
coalesce(t1.value,t2.value) as value
Фактически оба d1
и d2
будут освобождены, потому что они оба в стеке. То, что не освобождено, это объект Data
, который вы разместили в своей функции getData ()
. Вы можете увидеть это немного яснее, если уточнить свой класс Data
с помощью инструментов в конструкторах и деструкторе. Например:
class Data {
public:
Data() { cout << "Data default ctor" << endl; }
Data(const Data& other) { cout << "Data copy ctor" << endl; }
~Data() { cout << "Data dtor" << endl; }
static Data& getData()
{
Data *i = new Data();
return *i;
}
};
Обратите внимание, что я явно объявил конструктор копирования для Data
. В вашем примере вы неявно вызываете этот конструктор, когда выполняете Data d1 = getData ();
, и я подозреваю, что именно отсюда и ваша путаница. Теперь, если я запускаю эту простую программу:
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
Data d1 = Data::getData();
Data d2;
return 0;
}
Вывод будет следующим:
Data default ctor
Data copy ctor
Data default ctor
Data dtor
Data dtor
Строчка за строкой, вот что вы видите:
d1
- это объект стека, созданный на основе копии, возвращенной из getData ()
. d1
освобожден, но объект, созданный в , getData ()
утечка.
Единственный раз, когда вы восстанавливаете свою память, это когда ОС автоматически восстанавливает ее после завершения программы. Во время выполнения вашей программы то, что вы разместили, приведет к утечке памяти, поскольку C ++ не имеет встроенного сборщика мусора и требует ручного управления памятью для выделенных объектов кучи.
d1
и d2
оба являются стековыми объектами, поэтому будут уничтожены в конце проблема заключается в том, что getData ()
создает новый объект кучи, который никогда не удаляется. d1
инициализируется копией из ссылки на этот объект кучи, а сам d1
будет корректно уничтожен в конце exampleFunc
, но объект кучи генерируется в каждом из них. вызов getData ()
не будет удален.
С подписью, что getData ()
можно удалить этот объект, но возвращая ссылку на то, что нужно удалить не является идиоматическим интерфейсом.
Работает, но не является хорошим интерфейсом:
Data& d = getData();
delete &d;
That is typical "way of thining" of Java/C# programmers.
In C++ you may actually use value types much more than you think:
Data getData()
{
Data i;
return i;
}
void exampleFunc()
{
Data d1 = getData();
/* d1 is constructed here and destroyed */
Data d2;
}
If you want to return pointer, for example when you have some derived class that just use smart pointer like auto_ptr
that allows movement of ownership:
auto_ptr<Data> getData()
{
auto_ptr<Data> i(new Data());
return i;
}
void exampleFunc()
{
auto_ptr<Data> d1 = getData();
/* now d1 is destroyed when goes out of scope */
Data d2;
}
Если быть точным, ответ на ваш вопрос - да.
В этом коде:
int main()
{
Data* d = new Data();
return 0; //end of execution
}
данные на который указывает d автоматически освобождается операционной системой по окончании выполнения.
Другими словами, все данные, которые были выделены программой, которая завершилась, но не были отменены она (программа) будет освобождена ОС после (не во время) выполнения.
Вы правы в этом. Вы должны явно освободить память, используя delete или delete [].