В общем с ходу можно предположить два варианта, простой и правильный.
Простой вариант - исходя из вашего когда, вам не нужно удалять output. Заведите в main новую переменную для результата, и удаляйте её в конце метода main:
const auto* test2 = testMatrix->mulVec(test);
delete test2;
Правильный вариант заключается в том, чтобы по возможности вообще никогда не использовать сырые указатели. Т. е. примерно так (код не проверял, что-то может быть нужно чуть-чуть по-другому написать, но основная идея такая):
class Matrix4x4{
public:
float* data = new float[16];
std::shared_ptr<Vector> mulVec(std::shared_ptr<Vector> inp){
const auto output = std::make_shared<Vector>(...);
/*...*/
return output;
}
}
int main(){
const auto test = std::make_shared<Vector>(1, -1, 1);
const auto testMatrix = std::make_sharedMatrix4x4>();
const auto mulResult = testMatrix->mulVec(test);
}
Умный указатель сам позаботится о том, чтобы очистить память. Вместо shared_ptr можно конечно и другие указатели использовать, возможно правильно будет значение return обернуть в std::move.