Like many people, I made my own seq-like purely as an exercise to understand 
how Nim low-level memory management works. I was excited to find in the docs 
the `create` and `resize` procs, but `resize` eludes me. It doesn't appear to 
do much. Below is my minimum example with a working version using `create` and 
one that doesn't work with `resize`. Also, where can I read the source for 
`realloc`? [This line in 
system.nim](https://github.com/nim-lang/Nim/blob/89b39ee8fe271d0e1b75c15a4c6cf82eb9c13aea/lib/system.nim#L2426)
 is as far as I got - looks like a forward declaration?
    
    
    # nim --version 1.1.1 2020-02-15 (devel)
    # GCs: only ``none`` and ``refc`` allow the manual method below to work okay
    # ``boehm`` and ``arc`` produce corrupted memory (if I'm doing it right)
    # I use compile-time defines to switch between the two methods
    
    import strformat
    
    type MyArray[T] = object
      data:ptr UncheckedArray[T]
      len:Natural
      reserved:Natural
    
    proc newMyArray[T]():MyArray[T] =
      result.reserved = 32
      result.len = 0
      result.data = create(T=UncheckedArray[T], size=result.reserved)
    
    proc append[T](self:var MyArray[T],val:T) =
      if unlikely(self.len == self.reserved):
        when defined(debug):
          echo &"Allocating new memory {self.reserved} to {self.reserved shl 1}"
        self.reserved = self.reserved shl 1
        
        when defined(manual):
          var newmem = create(T=UncheckedArray[T], size=self.reserved)
          copyMem(newmem, self.data, sizeof(T)*self.len)
          dealloc self.data
          self.data = newmem
        
        when defined(fancyresize):
          var newmem = resize(self.data, self.reserved)
          # cast[int](self.data) is same before and after resize() call
          # self.data now corrupted
          #cast[int](newmem) is always 0
      
      self.data[self.len] = val
      inc self.len
    
    proc `$`[T](self:MyArray[T]):string =
      result = "["
      for i in 0..<min(self.len,1):
        result &= $self.data[i]
      for i in 1..<self.len:
        result &= "," & $self.data[i]
      result &= "]"
    
    when isMainModule:
      var arr = newMyArray[int]()
      for i in 0..<33:
        arr.append(i)
      echo arr
    
    
    Run

Reply via email to