Nim icon indicating copy to clipboard operation
Nim copied to clipboard

Illegal storage access with malloc and ARC/ORC

Open zeitbit opened this issue 2 years ago • 0 comments

What happened?

There is a problem (SIGSEGV: Illegal storage access. (Attempt to read from nil?)) compiling this code with -d:useMalloc and ARC or ORC:

type
    LinkedList*[T] = ref object
        head*: LinkedListNode[T]
        tail*: LinkedListNode[T]
        count: int

    LinkedListNode*[T] = ref object
        prev*: LinkedListNode[T]
        next*: LinkedListNode[T]
        data*: T

proc newLinkedList*[T](): LinkedList[T] =
    result       = new(LinkedList[T])
    result.head  = nil
    result.tail  = nil
    result.count = 0

proc newLinkedListNode*[T](data: T): LinkedListNode[T] =
    result      = new(LinkedListNode[T])
    result.prev = nil
    result.next = nil
    result.data = data

proc add*[T](self: LinkedList[T], data: T) =
    var node = newLinkedListNode(data)

    node.next = nil
    node.prev = self.tail

    if not self.tail.isNil:
        self.tail.next = node

    self.tail = node

    if self.head.isNil:
        self.head = node

    self.count += 1

proc remove*[T](self: LinkedList[T], node: LinkedListNode[T]) =
    if self.head == node:
        self.head = node.next

    if self.tail == node:
        self.tail = node.prev

    if not node.prev.isNil:
        node.prev.next = node.next

    if not node.next.isNil: # <---- **** CRASHES HERE ****
        node.next.prev = node.prev

    self.count -= 1

when isMainModule:
    var list = newLinkedList[int]()

    for i in 0 ..< 10_000:
        list.add(i)

    while list.count > 0:
        list.remove(list.tail)

    doAssert list.count == 0
    doAssert list.head.isNil
    doAssert list.tail.isNil

But with these changes in the remove function, it works correctly:

proc remove*[T](self: LinkedList[T], node: LinkedListNode[T]) =
    let
        prev = node.prev
        next = node.next

    if self.head == node:
        self.head = next

    if self.tail == node:
        self.tail = prev

    if not prev.isNil:
        prev.next = next

    if not next.isNil:
        next.prev = prev

    self.count -= 1

Nim Version

Nim Compiler Version 1.7.1 [Windows: amd64] Compiled at 2022-09-09 gcc (MinGW-W64 x86_64-msvcrt-posix-seh, built by Brecht Sanders) 12.2.0 Windows 10 Pro 21H2

Current Standard Output Logs

No response

Expected Standard Output Logs

No response

Possible Solution

No response

Additional Information

No response

zeitbit avatar Sep 09 '22 17:09 zeitbit