0

I thought I knew what the stack size argument in beginthread means. So my question is: why does this work?

#include <iostream>
#include <process.h>

using namespace std;

void huge_stack(int a, int b, int c, int d)
{
    int i[100000] = {0};
    cout << a << b << c << d << i[12333] << endl;
}

bool done = false;

void thread(void* p)
{
    huge_stack(1,2,3,4);
    done = true;
}

int main()
{
    _beginthread(thread, 10, nullptr);

    while(!done) {}

    return 0;
}

I made sure I'm building in Debug mode, so the calls and arrays won't be optimized.

Borislav Stanimirov
  • 1,609
  • 12
  • 23
  • 100.000 integers is about 400k of memory... hardly a *huge* array. – David Rodríguez - dribeas Oct 17 '12 at 16:38
  • 1
    I suspect that the parameter passed is an initial stack size only. It will be rounded up to the nearest [some multiple of page size, maybe 64k). If the stack overflows, it will be expanded by the virtual memory manager up to the stack size in the PE header - usually quite large. – Martin James Oct 17 '12 at 16:40
  • @DavidRodríguez-dribeas, still it's a lot more than the 10 bytes I thought I was giving :) – Borislav Stanimirov Oct 17 '12 at 16:44
  • @BorislavStanimirov - a Windows thread stack has a huge amount of gunge written to it before a single line of your thread code begins to execute. 10 bytes is hopelessly too small to even start, hence the rounding up by the OS to 64k or whatever. – Martin James Oct 17 '12 at 16:46
  • @MartinJames as you can see, I'm using much more than 64k, but it would be nice to know to how much it is rounded if this is indeed the case. – Borislav Stanimirov Oct 17 '12 at 16:48
  • 2
    http://blogs.technet.com/b/markrussinovich/archive/2009/07/08/3261309.aspx – Martin James Oct 17 '12 at 16:58
  • 3
    [Lots of details here](http://msdn.microsoft.com/en-us/library/windows/desktop/ms686774%28v=vs.85%29.aspx). – arx Oct 17 '12 at 17:59

1 Answers1

0

The reserve stack size is typically quite large... something like 1MB in Windows and 8MB in Linux. Note this is different than the commit size, which is where it starts, usually something along the lines of 4KB. The stack will grow automatically up to the reserve size. Also note on 32-bit systems, with large reserve stacks, you can run out of virtual address space fairly quickly with a few hundred threads (thus you can adjust this if needed using Windows link properties or Linux ulimit). Finally, for large objects, I'd recommend using the heap anyway.

mark
  • 5,269
  • 2
  • 21
  • 34
  • 1
    The important point is that the argument in beginthread specifies the commit size, not the reserve size, i.e., it specifies a minimum, not a maximum. – Harry Johnston Oct 17 '12 at 19:31