Swift 5.7.1中C字符串转Swift字符串失效问题求助
Swift 5.7.1中description返回空字符串的原因及解决办法
问题核心
原代码失效的根源是临时数组的生命周期问题,和手动分配空间无关:
- 你写的
UnsafeRawPointer([self.s])是先创建了一个仅包含self.s的临时数组,再取这个数组的内存指针 - Swift的ARC会立即回收这个临时数组,导致你拿到的指针变成野指针
- 旧版Swift/Xcode中,这块临时内存可能还没被覆盖,所以能“侥幸”读到值;但Swift 5.7.1的内存管理优化让临时对象的内存被立即释放/清空,因此返回空字符串
另外还有一个隐藏问题:C字符串要求以\0(空字符)结尾,原代码的临时数组里没有添加结束符,即使内存没被回收,也可能因为找不到结束符导致读取异常。
正确写法
分两种情况处理:
情况1:self.s是单个CChar(Int8)字符
需要手动添加字符串结束符,并确保指针在数组生命周期内被使用:
public var description: String { // 创建包含字符+结束符的数组,用withUnsafeBytes确保数组存活到字符串创建完成 return [self.s, 0].withUnsafeBytes { buffer in String(cString: buffer.baseAddress!.assumingMemoryBound(to: CChar.self)) } }
情况2:self.s是指向C字符串的UnsafePointer
这种情况不需要额外处理数组,直接用指针初始化字符串即可:
public var description: String { return String(cString: self.s) }
总结
原代码的本质是错误地使用了临时对象的指针,Swift 5.7.1只是让这种不安全的行为暴露出来,而非之前的“偶然可用”。不需要手动分配空间,只要保证指针指向的内存在使用时是有效的,并且符合C字符串的结尾要求即可。
内容的提问来源于stack exchange,提问作者tofutim
相关产品推荐
相关产品推荐

