簡體   English   中英

線程 1:EXC_BAD_ACCESS(代碼=2,地址=0x16d0f3ff0)

[英]Thread 1: EXC_BAD_ACCESS (code=2, address=0x16d0f3ff0)

我正在開發一個應用程序(在XCode版本 11.2 和 Swift 4.2 中),我在其中填寫了一個 LinkedList,在使用它之后,刪除組成它的元素會產生Thread 1 error: EXC_BAD_ACCESS (code = 2, address = 0x16d0f3ff0) 即使不使用列表中的項目,錯誤也會發生,只需添加它們並嘗試消除它們,錯誤已經發生。 我正在使用帶有IOS version 11.4.1的 iPhone 進行的測試

LinkedList的實現如下:

import Foundation

public class Node<T> {

    var value: T
    var next: Node<T>?
    weak var previous: Node<T>?

    init(value: T) {
        self.value = value
    } // init
} // Node

public class LinkedList<T> {

    private var head: Node<T>?

    private var tail: Node<T>?

    public private(set) var count: Int = 0

    public init() { } // init

    public var isEmpty: Bool {
        return  self.head == nil
    } // isEmpty

    public var first: Node<T>? {
        return  self.head
    } // first

    public var last: Node<T>? {
        return  self.tail
    } // last

    public func nodeAt(index: Int) -> Node<T>? {
        if index >= 0 {
            var node =  self.head
            var i = index
            while node != nil {
                if i == 0 {
                    return node
                } // if

                i -= 1
                node = node!.next
            } // while
        } // if

        return nil
    } // nodeAt

    public func removeAll() {
        self.head = nil
        self.tail = nil

        self.count = 0
    } // removeAll

    public func remove(node: Node<T>?) -> String {
        if isEmpty {
            return String("ERROR: Empty list, nothing to remove.")
        } // if

        guard node != nil else {
           return String("ERROR: Invalid node, nothing to remove.")
        } // guard

        let prev = node?.previous
        let next = node?.next

        if next != nil && prev == nil {
            self.head = next
            next?.previous = nil
        } else if next != nil && prev != nil {
            prev?.next = next
            next?.previous = prev
        } else if next == nil && prev != nil {
             self.tail = prev
            prev?.next = nil
        } // if
        node?.previous = nil
        node?.next = nil

        self.count -= 1
        return String("Successfully removed node: \(node!.value)")
    } // remove

    func enqueue(value: T) {
        let newNode = Node(value: value)

        if let tailNode =  self.tail {
               newNode.previous = tailNode
               tailNode.next = newNode
        } else {
                self.head = newNode
        } // else
        self.tail = newNode
        self.count += 1
    }

    func enqueue_first(value: HexRecord) {
        let newNode = Node(value: value)

        if let headNode = self.head {
            newNode.next = headNode
            headNode.previous = newNode
        } 
        self.head = newNode
        self.count += 1
    }

    func dequeue() -> T? {
        let element =  self.head?.value
        self.head =  self.head?.next
        self.count -= 1

        return element
    }

} // LinkedList

相同的節點屬於 HexRecord 類型:

public class HexRecord
{
    private var length: Int = 0
    private var address: Int64 = 0
    private var type: Int32 = 0
    private var data = [UInt8] ()
    private var checksum: UInt8 = 0

    init()
    {

    }

    public func getAddress() -> Int64 {
        return address;
    }

    public func getType() -> Int32 {
        return type;
    }

    public func getData() -> [UInt8] {
        return data;
    }

    public func getLength() -> Int {
        return length;
    }

    public func getChecksum() -> UInt8 {
        return checksum;
    }


    public func setAddress(address: Int64) {
        self.address = address;
    }

    public func setData(data: [UInt8]) {
        self.data = data;
    }

    public func setLength(length: Int) {
        self.length = length;
    }

    public func setType(type: Int32) {
        self.type = type;
    }

    public func setChecksum(checksum: UInt8) {
        self.checksum = checksum;
    }
}

它的用法如下:

func tratar_registros() {

    var records = LinkedList<HexRecord>();

    ....

    let data_line: HexRecord? = try parseRecord(line: line)  // parseRecord convert String to HexRecord
    if (data_line != nil)
    {
        records.enqueue(value: data_line!)
    }
    ....

    records.removeAll();        //Thread 1: EXC_BAD_ACCESS (code=2, address=0x16d0f3ff0)

} // Thread 1: EXC_BAD_ACCESS (code=2, address=0x16d0f3ff0)     if there is no line records.removeAll();

使用調試器,我看到將值 nil 分配給 self.head 時發生錯誤。 就在 self.head 具有正確值之前,它變為 nil 並在到達下一條指令之前跳過錯誤(在 removeAll 函數中)

在 Debug Navigator 中,在 stackTrace 中看到錯誤的最后兩個函數:

libobjc.A.dylib`_object_remove_assocations:
    0x180d11eec <+0>:   sub    sp, sp, #0x70             ; =0x70 
->  0x180d11ef0 <+4>:   stp    x26, x25, [sp, #0x20]  //Thread 1 error: EXC_BAD_ACCESS (code = 2, address = 0x16d0f3ff0)
    0x180d11ef4 <+8>:   stp    x24, x23, [sp, #0x30]

libswiftCore.dylib`_swift_release_:
    0x104e18d1c <+180>: bl     0x104e1a37c               ; bool swift::RefCounts<swift::SideTableRefCountBits>::doDecrement<(swift::PerformDeinit)1>(unsigned int)
->  0x104e18d20 <+184>: ldp    x29, x30, [sp], #0x10. //Thread 1 error: EXC_BAD_ACCESS (code = 2, address = 0x16d0f3ff0)
    0x104e18d24 <+188>: ret    

有人知道如何解決嗎?

謝謝!

就我而言,當我創建循環引用時發生了此錯誤。

我創建了一個列 object,並在列初始化程序中計算了要創建的列數。 為了計算該列表,該 getter 初始化了一個列數組。

通過更改 LinkedList 的 removeAll 方法解決了以下問題:

public func removeAll() {
    while head != nil {
        removeTail()
    }
} 


public func removeTail() {
    guard let tail = tail else {return}
    if let prev = tail.previous {
        prev.next = nil
        self.tail = prev
    } else {
        self.head = nil
        self.tail = nil
    }
    count -= 1


    if count < 0 { count = 0}
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM