Classes on stack

Steven Schveighoffer schveiguy at gmail.com
Thu Sep 1 13:23:42 UTC 2022


On 9/1/22 6:13 AM, Redwan wrote:
> On Thursday, 1 September 2022 at 09:53:08 UTC, Dennis wrote:
>> On Thursday, 1 September 2022 at 09:43:55 UTC, Redwan wrote:
>>> oh, thank you. with this, no allocation??
>>
>> No heap allocation. The `@nogc` attribute is enforced by the compiler, 
>> so you will get an error if you use `new` without `scope` here.
> 
> 
> OK tnx. another problem that probably is related to this issue.
> I compiled this worthless code:
> ```
> void main() {}
> ```
> 
> also this one:
> ```
> @nogc void main() {}
> ```
> 
> 
> the valgrind result:
> ```
> ...
> total heap usage: 143 alloc, 141 frees, 13,236 bytes allocated
> ...
> ```
> 
> !!!
> what's this means??
> from where comes this allocations and also leaks???

The runtime does some allocations before running main. But these are all 
C malloc allocations and not GC allocations. There should be zero GC 
usage in these programs.

As for "leaks", I think it would tell you that. Looking on the internet, 
this may count for "reachable" data, that is, data that is allocated, 
and still referenced at program exit. Such memory is not a "leak" in the 
sense that you just stopped pointing at it and never freed it.

I suggest you look at the remaining valgrind outputs. This is what I got:

```
$ valgrind --leak-check=full --show-leak-kinds=all ./testmemleak
==418523== Memcheck, a memory error detector
==418523== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==418523== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright 
info
==418523== Command: ./testmemleak
==418523==
==418523==
==418523== HEAP SUMMARY:
==418523==     in use at exit: 96 bytes in 2 blocks
==418523==   total heap usage: 149 allocs, 147 frees, 14,896 bytes allocated
==418523==
==418523== 24 bytes in 1 blocks are still reachable in loss record 1 of 2
==418523==    at 0x483B723: malloc (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==418523==    by 0x483E017: realloc (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==418523==    by 0x14E10D: 
_D4core8internal9container6common8xreallocFNbNiPvmZQe (in 
/home/steves/testmemleak)
==418523==    by 0x15C095: 
_D4core8internal2gc4impl5protoQo7ProtoGC8addRangeMFNbNiPvmxC8TypeInfoZv 
(in /home/steves/testmemleak)
==418523==    by 0x14E3FF: gc_addRange (in /home/steves/testmemleak)
==418523==    by 0x150275: 
_D2rt6memory16initStaticDataGCFZ14__foreachbody1MFNbNiKSQCc19sections_elf_shared3DSOZi 
(in /home/steves/testmemleak)
==418523==    by 0x152657: 
_D2rt19sections_elf_shared3DSO7opApplyFMDFKSQBqQBqQyZiZi (in 
/home/steves/testmemleak)
==418523==    by 0x150218: _D2rt6memory16initStaticDataGCFZv (in 
/home/steves/testmemleak)
==418523==    by 0x14ECF8: rt_init (in /home/steves/testmemleak)
==418523==    by 0x14BB27: 
_D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv (in 
/home/steves/testmemleak)
==418523==    by 0x14BAC5: 
_D2rt6dmain212_d_run_main2UAAamPUQgZiZ7tryExecMFMDFZvZv (in 
/home/steves/testmemleak)
==418523==    by 0x14BA2E: _d_run_main2 (in /home/steves/testmemleak)
==418523==
==418523== 72 bytes in 1 blocks are still reachable in loss record 2 of 2
==418523==    at 0x483DFAF: realloc (in 
/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==418523==    by 0x17C0E1: _d_register_manual_gc (in 
/home/steves/testmemleak)
==418523==    by 0x18455C: __libc_csu_init (in /home/steves/testmemleak)
==418523==    by 0x48B703F: (below main) (libc-start.c:264)
==418523==
==418523== LEAK SUMMARY:
==418523==    definitely lost: 0 bytes in 0 blocks
==418523==    indirectly lost: 0 bytes in 0 blocks
==418523==      possibly lost: 0 bytes in 0 blocks
==418523==    still reachable: 96 bytes in 2 blocks
==418523==         suppressed: 0 bytes in 0 blocks
==418523==
==418523== For lists of detected and suppressed errors, rerun with: -s
==418523== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
```

The 72 bytes allocated was to register the manual GC, which is run 
before even C's main runs.

The 24 bytes was allocated to add a range in the runtime initialization. 
It looks like it's this line: 
https://github.com/dlang/dmd/blob/09d04945bdbc0cba36f7bb1e19d5bd009d4b0ff2/druntime/src/rt/memory.d#L24

Note, however, that prior to the GC being used to actually allocate 
anything, it's *not* initialized. Instead it is a specialized object 
that will just malloc this range until the real GC is set up. It's not a 
leak because it's still in use when the program exits.

-Steve


More information about the Digitalmars-d mailing list