Yes and no.
Yes insofar as you can of course allocate whatever you please and pass those
pointers around and/or use them. No insofar as you must be careful to not
wildly mix up Nim-allocated objects and pointers. In your example
proc newMyObj(): MyObj =
result = MyObj(x: 42)
proc allocMyObj(): ptr MyObj =
result = cast[ptr MyObj](alloc(sizeof(ptr MyObj)))
result[] = newMyObj()
Run
there are multiple problems. For one `result[] = newMyObj()` says "return what
result points to" which however is not a pointer. More gravely though, even if
it worked you would lose the just allocated pointer/memory because you would
overwrite `result` with what `MyObj()` returns.
What you actually wanted is probably this:
proc allocMyObj(): ptr MyObj =
result = cast[ptr MyObj](alloc(sizeof(MyObj)))
result[].x = 42
Run
Alternatively you could also use your `newMyObj()` proc _instead_ of
`allocMyObj()` but then your object were a Nim (allocated) object and taking
its address to have a pointer to pass around (to C code) would risk to end in a
weird situation because from Nims point of view _it_ is in charge of that
object while from C's point of view it could do with that pointer whatever it
pleases and assume its - not guaranteed - existence etc.
Maybe the following code can help you to see what I mean
type
MyObj = object
x: int
proc newMyObj(v: int): MyObj =
result = MyObj(x: v)
proc allocMyObj(): ptr MyObj =
result = cast[ptr MyObj](alloc(sizeof(MyObj)))
var tmp = newMyObj(42) # under the hood a Nim ref
echo "tmp: " & tmp.repr() & "tmp address: " & repr(tmp.addr()) # show it
from Nim's point of view
echo "allocated object: " & result.repr() # now show the alloc'd object
result = tmp.addr() # but return the other one bc. result has been
overwritten
# -- main --
let mo = allocMyObj()
# the allocated object is lost. We have no way to access or free it
echo "After allocMyObj(): " & mo.repr()
mo.dealloc() # deallocates which one? Obviously *not* the alloc'd one
let mo2 = newMyObj(43) # try it the other way
echo "After newMyObj(): " & mo2.repr()
Run