【问题标题】:Pointer being freed was not allocated [Swift]未分配被释放的指针 [Swift]
【发布时间】:2019-03-13 11:56:01
【问题描述】:

我正在尝试读取 TCP 套接字连接中的长字符串。 对于读取短长度的字符串,它工作正常。但是当我尝试发送长长度的 base64 编码图像时。它崩溃了,我试图增加到maxReadLength = 10000,但它仍然无法正常工作。

读取传入消息

 private func readAvailableBytes(stream: InputStream) {
            let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: maxReadLength)

            while stream.hasBytesAvailable {
                let numberOfBytesRead = inputStream.read(buffer, maxLength: maxReadLength)

                if numberOfBytesRead < 0 {
                    if let _ = inputStream.streamError {
                        break
                    }
                }

           ❌ Crashing in  below line ???? ❌

               if let reciviedMsg = String(bytesNoCopy: buffer,
                                         length: numberOfBytesRead,
                                         encoding: .ascii,
                                         freeWhenDone: true)
               {
                   delegate?.scoktDidRecivceNewMessagew(message: reciviedMsg)
                }

            }
        }

错误

malloc: *** error for object 0x101890c00: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

【问题讨论】:

    标签: swift tcp tcpclient


    【解决方案1】:

    问题是缓冲区只分配一次,但每次都被释放 时间

     String(bytesNoCopy: buffer, length: numberOfBytesRead, encoding: .ascii, freeWhenDone: true)
    

    被调用。这是一个简短的独立示例来演示该问题:

    let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: 4)
    memcpy(buffer, "abcd", 4)
    
    var s = String(bytesNoCopy: buffer, length: 4, encoding: .ascii, freeWhenDone: true)
    // OK
    
    s = String(bytesNoCopy: buffer, length: 4, encoding: .ascii, freeWhenDone: true)
    // malloc: *** error for object 0x101d8dc40: pointer being freed was not allocated
    

    使用freeWhenDone: false 是解决问题的一种选择,但请注意 你最终必须释放缓冲区。

    另一种方法是使用Array(或Data)作为缓冲区,这是自动的 函数返回时释放。示例:

    var buffer = [UInt8](repeating: 0, count: maxReadLength)
    while inputStream.hasBytesAvailable {
        let numberOfBytesRead = inputStream.read(&buffer, maxLength: maxReadLength)
        if numberOfBytesRead < 0 {
            break
        }
        if let receivedMsg = String(bytes: buffer[..<numberOfBytesRead], encoding: .ascii) {
            // ...
        }
    }
    

    【讨论】:

    • 好的,谢谢您的回答,我会尝试解决方案。通过 TCP 套接字发送 Base64 编码的图像是好是坏?
    • if let receivedMsg = String(bytes: buffer[..&lt;numberOfBytesRead], encoding: .ascii) { } 你能描述一下吗?,,,,,它不适合我,,,,..&lt;numberOfbytesRead 给出错误Cannot convert value of type 'PartialRangeUpTo&lt;Int&gt;' to expected argument type 'Int'
    • @Dhiru:上面的代码在我的 Xcode 10 中编译没有问题。
    • 好的,我不知道为什么它在我的 Xcode (10.0) 上显示错误你能看到这个吗..imgur.com/a/yMLZnmE
    • 这个惊人的@MartinR 答案只有 3 票,这有点令人遗憾。我选择了替代方案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2018-09-30
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多