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

Reply via email to