Open darkestpigeon opened 1 month ago
It's also ok if access obj
before try:
, such as,
import std/os
type MyObj = object
data: pointer
size: int
proc initMyObj(size: int): MyObj =
assert size > 0
result.data = allocShared0(size)
result.size = size
# imitate work
let p = cast[ptr UncheckedArray[uint8]](result.data)
for i in 0..<size:
p[i] = i.uint8
proc `=destroy`(x: MyObj) =
if not x.data.isNil:
deallocShared(x.data)
proc `=wasMoved`(x: var MyObj) =
x.data = nil
x.size = 0
proc `=copy`(x: var MyObj, y: MyObj) {.error.}
proc main() =
while true:
var obj: MyObj
discard obj
try:
obj = initMyObj(10_000_000)
except:
# except FloatOverflowError: also causes a leak, although it is never raised
break
# discard obj
obj = MyObj()
sleep(20)
echo getOccupiedMem()
main()
>except
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
@darkestpigeon I find that this problem doesn't exist in nim-1.6.20 with --mm:orc
or --mm:orc
, but memory leak 48 bytes
with --mm:refc
.
import std/os
type MyObj = object
data: pointer
size: int
proc initMyObj(size: int): MyObj =
assert size > 0
result.data = allocShared0(size)
result.size = size
# imitate work
let p = cast[ptr UncheckedArray[uint8]](result.data)
for i in 0..<size:
p[i] = i.uint8
proc `=destroy`(x: var MyObj) = # Using `var` in nim-1.6.20
if not x.data.isNil:
deallocShared(x.data)
proc `=wasMoved`(x: var MyObj) =
x.data = nil
x.size = 0
proc `=copy`(x: var MyObj, y: MyObj) {.error.}
proc main() =
while true:
var obj: MyObj
try:
obj = initMyObj(10_000_000)
except:
# except FloatOverflowError: also causes a leak, although it is never raised
break
# discard obj
obj = MyObj()
sleep(20)
echo getOccupiedMem()
main()
>except
0
0
0
0
0
0
0
0
0
0
...
Description
Object destructor not called when reassigning after a
try-except
block.Minimal example:
Uncommenting the
discard obj
line removes the issue.Nim Version
Both on
and
Current Output
Expected Output
Known Workarounds
In the example above, uncommenting the
discard obj
line removes the issue.Additional Information
No response