When removing M elements (M==j-i), all elements beyond j are shifted M positions to the left. This means that M values on the right are now beyond the length of the result slice, but still within capacity, and still reachable through the original slice argument. If the elements are references or pointers or contain pointers, then these elements won't be GC'ed, which is a memory leak.
There is no reason for these M values on the right to be reachable at all from any slice header. Zeroed values would make more sense.
There is no check to make sure that i<=j, and the case i>j yields a result that violates the documentation of Delete.
I suggest fixing this by explicitly zeroing the tail of the original slice, and by explicitly checking that i<=j.
The memory leak (1) doesn't exist for non-pointer value types.
Zeroing the right tail fixes (1) for pointer types and changes the values visible from the original slice header. This is okay because Delete is a destructive function and makes no promise to keep the extra capacity unchanged.
The documentation says "Delete panics if s[i:j] is not a valid slice of s." which is currently not true because s[2:1] is not a valid slice (see https://go.dev/play/p/ftvpm65GGzL) but instead of panicking, Delete produces non-sensical results (see https://go.dev/play/p/sIJRru2sGPa). The new suggested implementation fixes this bug.
I will send a change containing the suggested implementation, and extra test cases.
The text was updated successfully, but these errors were encountered:
Now doing an explicit bounds check, to panic on invalid indices
Fixes part (3) of golang/go#54650
Auto-Submit: Keith Randall <email@example.com>
TryBot-Result: Gopher Robot <firstname.lastname@example.org>
Run-TryBot: Keith Randall <email@example.com>
Reviewed-by: Keith Randall <firstname.lastname@example.org>
Reviewed-by: Keith Randall <email@example.com>