質問に対する答えは次のとおりです。はい、CoTaskMemFree を使用して、CoTaskMemAlloc で割り当てられたメモリを解放する必要があります。
他の回答は、COM サーバーと COM クライアントの間で渡されるメモリに CoTaskMemAlloc と CoTaskMemFree が必要な理由を説明していますが、質問には直接答えていません。
あなたの先生は正しかった: どのリソースにも、対応するリリース関数を常に使用する必要があります。new を使用する場合は、delete を使用してください。malloc を使用する場合は、free を使用してください。CreateFile を使用する場合は、CloseHandle を使用します。等。
さらに良いことに、C++ では、コンストラクタでリソースを割り当て、デストラクタでリソースを解放する RAII オブジェクトを使用し、そのままの関数の代わりにこれらの RAII ラッパーを使用します。これにより、例外のようなものが発生した場合でも、リークしないコードを簡単かつクリーンに記述できます。
標準テンプレート ライブラリは、RAII を実装するコンテナーを提供します。そのため、裸のメモリを割り当てて自分で管理しようとするのではなく、std::vector または std::string の使用方法を学ぶ必要があります。std::shared_ptr や std::unique_ptr などのスマート ポインターもあり、適切なリリース呼び出しが常に適切なタイミングで行われるようにするために使用できます。
ATL は、COM オブジェクトの参照カウントを処理するラッパー オブジェクトである ATL::CComPtr のようないくつかのクラスを提供します。これらは、正しく使用するのに絶対確実というわけではありません。実際、最新の STL クラスのほとんどよりも落とし穴がいくつかあるため、ドキュメントを注意深く読んでください。正しく使用すると、AddRef 呼び出しと Release 呼び出しがすべて一致することを確認するのは比較的簡単です。