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 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