C maximum size in main [duplicate]
Possible Duplicate:
C programming, why does this large array declaration produce a segmentation fault?
This is my first time here so sorry if I break some rules or if this has been answered before. I recently made a C program in which I had a matrix of
char buff[NR][1024*1024];
I needed NR = 128. So the program would alocate 128MB. This was in main(). I tried it on a few systems with enough memory with no error on compile. At runtime I recieved segmentation fault on all systems. It worked for NR = 7, but not 8. I moved that code outside of main making it global. It didn't crash anymore even for 128. Does anyone know why this happened? The compiler was GCC
The problem is you are overflowing the stack which is typically just a few MB in size (the exact size depends on the system and your compiler options). You could allocate the memory on the heap instead using malloc
.
When you put it in main()
it allocates the 128MB on the stack, and the stack is usually limited, with the limit varying from system to system. Some might allow you only 8MB, others as much as you can take -- your limit seems to be 8MB, which is standard for most Linux platforms. If this is a POSIX-like environment, you could try controlling the limit with ulimit -s
.
When you take the declaration out of main()
and make it static it will end up in the BSS segment (unless you initialize it), and be constrained only by heap space on most systems (which is usually very large and/or unlimited). See http://en.wikipedia.org/wiki/Data_segment
However, if you want it locally and ad hoc, consider allocating the NR megabytes yourself:
#define MB (1024*1024)
char *bufp = malloc(NR*MB)
char *buf[NR];
int i;
for (i = 0; i < NR; i++)
buf[i] = bufp + i*MB;
You could also allocate each MB chunk separately, but I did it this way in case you want the whole area to be contiguous in memory. Remember to free(bufp)
when you're done if you're writing a library of if your program will move on to do something else.
Your array is allocated on stack. Stack has limited size (depends on os and linker settings). I think default stack size is approximately 1 megabyte for win32(msvc compiler), and 8 megabytes for linux(gcc). Anything larger than that will cause stack overflow, which will cause instant segfault.
Possible solutions:
- Increase stack size in linker settings.
- Allocate memory dynamically (using malloc).
- Make array global.
- Make array static.
Making variable global/static will cause (on compilers I've seen, at least) it to be allocated outside of stack - either in data or code segment, which will not affect stack size.
Or you can increase stack allocation size for your programm. For example in VS 2008 go to Project Properties -> Linker -> and set Stack Commit Size.
You can use malloc, you can often also declare it outside of main using file scope. If you need it in another c file look into using extern. This method is not recommended unless you have a really good reason to have a file scoped variable (note c does not really have "global" variables, just file scope ones that you can access with extern). Google is your friend on these techniques as well :) . You can also usually find the setting for maximum stack size that goes along with your compiler/OS. Look for "set stack size ". Again not recommended, learn to use malloc :) .
The segmentation fault probably had another reason. Use a debugger such as gdb to determine where exactly the segmentation fault happened.
精彩评论