testing if data is allocated on the stack or heap

Biotronic simen.kjaras at gmail.com
Wed Oct 18 07:02:26 UTC 2017


On Tuesday, 17 October 2017 at 23:59:19 UTC, Steven Schveighoffer 
wrote:
> On 10/17/17 7:32 PM, flamencofantasy wrote:
>> On Tuesday, 17 October 2017 at 17:27:17 UTC, Biotronic wrote:
>>> On Tuesday, 17 October 2017 at 15:33:02 UTC, drug wrote:
>>>> [...]
>>>
>>> I have very little knowledge about sbrk, so here's my 
>>> solution.
>>>
>>> Tested on win32 and win64.
>>>
>>> [...]
>> 
>> Try this;
>> 
>> unittest {
>>      int[5*1024] n;
>>      int* p = new int;
>> 
>>      assert(n.onStack);
>>      assert(!p.onStack);
>> }
>
> The second is wrong. You are asserting that the storage of p is 
> not on the stack, but it is.
>
> What p *points at* is not on the stack.
>
> So the correct call should be:
>
> assert(!(*p).onStack);
>
> or (IMO) less ugly: assert(!onStack(*p));
>
> -Steve

No, the second is correct - the ref overload is only chosen when 
p is not implicitly castable to void*. In fact, the second assert 
passes, it's the first one that causes problems.

I've written an improved version, that probably still has 
problems. If flamencofantasy would like to point out other 
shortcomings, I'd love to learn.

module stackCheck;

private size_t stackStart;
enum size_t pageSize = 0x1000;

static this() {
     import core.stdc.stdlib : alloca;
     stackStart = cast(size_t)alloca(size_t.sizeof);
}

bool onStack(void* p) {
     size_t end = cast(size_t)&p;
     size_t pp = cast(size_t)p;
     size_t ss = stackStart;

     if (end > ss) {
         end &= ~(pageSize-1);
         ss  &= ~(pageSize-1);
         end += pageSize;
         return pp >= ss && pp <= end;
     } else {
         end &= ~(pageSize-1);
         ss  &= ~(pageSize-1);
         ss += pageSize;
         return pp <= ss && pp >= end;
     }
}

bool onStack(T)(ref T p) {
     return (&p).onStack;
}

unittest {
     int n;
     int* p = new int;

     assert(n.onStack);
     assert(!p.onStack);
}

unittest {
     int[5*1023] n;
     int* p = new int;

     assert(n.onStack);
     assert(!p.onStack);
}


More information about the Digitalmars-d-learn mailing list