如果我在函数中返回原始字符串的一部分,原始字符串会被释放吗?

Will the original string be freed if I return a portion of it in a function?

提问人:A-yon Lee 提问时间:11/13/2023 最后编辑:Jonathan HallA-yon Lee 更新时间:11/13/2023 访问量:67

问:

我了解到,当使用方括号取字符串的一部分时,Go 不会创建一个新字符串,而是反映相同的底层字符串,类似于切片。

那么在下面的函数中,函数的返回部分是否会阻止原始字符串被释放并导致内存泄漏?

func Slice(str string, start int, end int) string {
    limit := len(str)

    if start < 0 {
        start = limit + start
    }

    if end < 0 {
        end = limit + end
    }

    if end > limit {
        end = limit
    }

    if start >= end || start >= limit {
        return "" // return an empty string directly
    }

    return str[start:end]
}
字符串 go

评论

1赞 JimB 11/13/2023
请参阅 stackoverflow.com/questions/65419268/...
0赞 Volker 11/13/2023
不,因为这不是实际的泄漏。

答:

3赞 icza 11/13/2023 #1

对字符串进行切片时,结果子字符串将与原始子字符串共享内存。这也意味着原始字符串将保留在内存中。

这是否被视为内存泄漏?取决于。通常内存泄漏表明内存使用量增加,在这种情况下,内存使用量不会增长,只是有些东西可能保留在内存中,您实际上不再需要/使用。

如果您知道您正在切片一个大字符串,并且不需要字符串的其余部分,则可以复制结果,以免使用字符串保留对原始大字符串的引用。Clone() 像这样:

return strings.Clone(str[start:end])

引用以下文档:strings.Clone()

Clone 返回 s 的新副本。它保证将 s 的副本复制到新的分配中,这在仅保留大得多的字符串的一个小子字符串时可能很重要。使用克隆可以帮助此类程序使用更少的内存。