I'm quite worried about whether or not it causes a memory leak, and how I can fix that in case it does.
It does. In main()
, you allocate memory and point v.t
to it; then you overwrite that pointer with one from the return value of fct()
. The original pointer is lost, and you've no other copy of it, so the pointed-to memory is leaked.
Oh, and I know that if I define another vector let's say w, such that w = fct(v) it would clear the problem, but I need a different method, one that would work even if the function is returned to the original vector.
With every dynamic memory allocation comes an obligation to free that memory. You can consider that obligation to be associated with exactly one copy of the pointer to that memory, as a kind of notional tag. You can freely (notionally) transfer the tag to a different copy of the pointer. If the copy then bearing the tag ever goes out of scope or is overwritten with a different value, however, then you leak the pointed-to memory.
Consider how that applies to your case:
You allocate memory and assign a pointer to v.t
. This is initially the only copy of the pointer to the allocated memory, so the obligation to free that memory is associated with it.
You pass a copy of v
, including a copy of v.t
, to function fct()
. You have two alternatives: the obligation to free can stay with the original copy of v.t
, or it can be transferred to the copy received by the function. That is an inherent characteristic of the definition of fct()
, and should be documented with it -- you cannot choose on a call-by-call basis. Since fct()
does not free the pointer, you have implicitly chosen for the obligation to free to remain with the original copy.
fct()
performs its own allocation and returns a copy of the resulting pointer; that's the only copy that survives the execution of the function, so the obligation to free must go with it.
By overwriting the original v.t
with a different value while it holds an obligation to free, you leak the original memory. There is still an obligation to free the (new) value of v.t
, but there is no longer any way to access the old dynamically-allocated memory.
Now you had one option in there: whether to transfer the obligation to free as part of the function call. Suppose that you did transfer it; in that case, fct()
must not fail to perform that free()
before it returns. In that case, however, main()
must not use the original value of v.t
after calling fct()
, whether it overwrites v
with that function's result or not.
So you have a choice: either fct()
takes responsibility for freeing v.t
(which it could pass on to another function if it wished, or which it could return to the caller via its return value), or fct()
does not take that responsibility. Its callers need to behave accordingly. You cannot have it both ways.