I am trying to create a very large array, to which, I then get the following error.
char largearray[1744830451];
warning LNK4084: total image size 1750372352 exceeds max (268435456); image may not run
I was told I could use a C-array and not C++ . I'm not sure I fully understood my friend's response. I am currently using Visual Studio 6.0 C++ . Do I need to get another compiler to do straight C or is it a method to how to declare the array that needs to change?
If I need to change compilers, does someone have suggestions?
The char array[size] syntax means the array will be created in the data section of your compiled program and not allocated at runtime.
Win32 PE code cannot exceed 256MB (according to your linker's error message), but the array you're declaring is 1.6GB in length.
If you want a 1.6GB array, use malloc (and don't forget to call free!)
...but why on earth are you running VC6?
If you predefine the size, then you are restricted to the stack size (stack has less size but faster), so it is better to define the size dynamically, which means your data is stored in heap (heap has bigger size but a little bit slower than stack).
Have a look at http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html which explains the difference of stack and heap.
I created a VC++ console application (HelloWorld). In that I created one byte array with size 1316779. It's working fine when building the application. Anyway debugging the application it's giving
Unhandled exception at 0x00969167 in HelloWorld.exe: 0xC00000FD: Stack overflow.
But when I changed size to 1010000 then it worked fine.
My requirement is to create a byte array size of 1316779. i.e. byte myArray[1316779];
I am working under XP operating system with Pentium processor and having 2GB RAM.
1316779 bytes = 1.31 MB
MSVC puts by default a 1 MB stack limit
/F - Without this option the stack size defaults to 1 MB.
You either need to increase that limit or reduce your stack size (e.g. use a heap allocation). I wouldn't rely on 1010000 as well (1.01).
Define the local array as having static storage duration
static byte myArray[1316779];
Otherwise use standard class std::vector
Obviously, 1316779 bytes are bigger than the stack and you're blowwing it up. So make the 1316779 bytes on the heap and pass a handle to that on the stack:
std::vector<byte> myHugeAmountofBytes;
myHugeAmountofBytes.reserve(1316779);
// put elemnts into myHugeAmountofBytes
myHugeAmountofBytes can now be passed via the stack with no overflow.
I try to create a ~975KB array on the stack and it crashes.
const int size = 500;
cout << (sizeof(float)*size*size)/1024 << endl;
float myArray[size*size]; // crash
This seems like a very small amount of space. Is there any way to know how much space is available (total and currently) before I initialize a variable?
The stack is limited in nearly all systems. How big it's allowed to be depends on the OS/Compiler combination. Putting VERY large amounts of data on the stack is a poor idea. Either use C++ standard types (e.g. vector) or use your own dynamic memory allocation. You never know when some other function adds a bit of extra stack, and all of a sudden, you go over the limit - best to not get anywhere near the max size of the stack.
In Visual C++ the default stack size is managed by the linker option /STACK (doc). By default it is 1 MB.
Note that each new thread will have its own stack, and you can specify the initial size with parameter dwStackSize in function CreateThread. If it is 0 it will default to the one used in the linker command.
About your other questions, there is no way to query the current/maximum stack size. To avoid problems it is better to use the heap for any significant memory allocation.
The default stack size for Visual Studio is 1MB, as Andre said you can use std::vector to avoid this problem or you can dynamically allocate memory. You can adjust the stack size on Visual Studio using /F. If there is not a compelling reason to allocate the data on the stack it probably makes more sense to use another option.
I was trying to declare a 1024 by 1024 float array but a window just popped up saying project_name.exe has stopped working... with options whether to debug or close program. Previously, I succeeded declaring 1000 by 2 int array. I've kind of searched the internet for possible cause, and they said its memory related issue, "stack/heap overflow" in exact. They said that it is even worse for the case of float.
I only need up to 5 or 6 decimal places.
Any advice or suggestion? I didn't face this issue in python nor in matlab. I am using Microsoft Visual Studio 2010.
Are you declaring this as a local variable in a function or method? If so it's a classic stack overflow. For VS2010 see http://msdn.microsoft.com/en-us/library/8cxs58a6%28v=vs.100%29.aspx
The reserve value specifies the total stack allocation in virtual memory. For x86 and x64 machines, the default stack size is 1 MB. On the Itanium chipset, the default size is 4 MB.
So a 1024x1024 array of floats (assuming 4 bytes per float) clocks in at a whopping 4mb - you've sailed right through the default stack limit here.
Note that even if you do have an Itanium you're not going to be able to use all of that 4mb - parameters, for example, will also need to be stored on the stack, see http://www.csee.umbc.edu/~chang/cs313.s02/stack.shtml
Now, you could just increase the stack size, but some day you're going to need to use a larger array, so that's a war of attrition you're not going to win. This is a problem that's best solved by making it go away; in other words instead of:
float stuff[1024 * 1024];
You declare it as:
float *stuff = new float[1024 * 1024];
// do something interesting and useful with stuff
delete[] stuff;
Instead of being on the stack this will now be allocated on the heap. Note that this is not the same heap as that mentioned by Robert Harvey in his answer; you don't have the limitations of the /HEAP option here.
Are you declaring this on the stack perhaps? Objects that big have to be on the heap!
I have a problem with my simple Fortran program. I am working in Fortran 77, using Compaq Visual Fortran. The program structure must be in the form of a main and a subroutine, because it is part of a big program related to the finite element method.
My issue is that I would like to set the values 10000 & 10000 for NHELE and NVELE respectively, but when I run the code, the program stops and gives the following error:
forrt1: server <170>: program Exception - stack overflow
I've tried iteratively reducing the required values, until I reached 507 & 507. At this point the code runs without errors.
However, increasing the values to 508 & 508 causes the same error to reappear.
I think the problem is related to the subroutine NIGTEE, because when I rearrange the program without it, everything works fine.
I've tried increasing the stack size to a maximum by using the menu project>>settings>>link>>output>>reserve & commit
but this didn't make a difference.
How can I solve this problem?
Here is my program:
PARAMETER(NHELE=508,NVELE=508)
PARAMETER(NHNODE=NHELE+1,NVNODE=NVELE+1)
PARAMETER(NTOTALELE=NHELE*NVELE)
DIMENSION MELE(NTOTALELE,4)
CALL NIGTEE(NHELE,NVELE,NHNODE,NVNODE,NTOTALELE,MELE)
OPEN(UNIT=7,FILE='MeshNO For Rectangular.TXT',STATUS='UNKNOWN')
WRITE(7,500) ((MELE(I,J),J=1,4),I=1,NTOTALELE)
500 FORMAT(4I20)
STOP
END
SUBROUTINE NIGTEE(NHELE,NVELE,NHNODE,NVNODE,NTOTALELE,MELE)
DIMENSION NM(NVNODE,NHNODE),NODE(4)
DIMENSION MELE(NTOTALELE,4)
KK=0
DO 20 I=1,NVNODE
DO 20 J=1,NHNODE
KK=KK+1
NM(I,J)=KK
20 CONTINUE
KK=0
DO 30 I=1,NVELE
DO 30 J=1,NHELE
NODE(1)=NM(I,J)
NODE(2)=NM(I,J+1)
NODE(3)=NM(I+1,J+1)
NODE(4)=NM(I+1,J)
KK=KK+1
DO 50 II=1,4
50 MELE(KK,II)=NODE(II)
30 CONTINUE
RETURN
END
Thanks.
Update:
Here's your actual problem. Your NM array is being declared as being a two-dimensional array of NHNODE cells by NVNODE rows. If that is 10,000 by 10,000, then you will need more than 381 megabytes of memory to allocate this array alone, aside from any other memory being used by your program. (By contrast, if the array is 500 by 500, you only need about 1 megabyte of memory for the same array.)
The problem is that old Fortran would allocate all the arrays directly in the code segment or on the stack. The concept of an OS "heap" (general purpose memory for large objects) had been invented by 1977, but Fortran 77 still didn't have any constructs for making use of it. So every time your subroutine is called, it has to push the stack pointer to make room for 381 megabytes of space on the stack. This is almost certainly larger than the amount of space your operating system is allowing for the stack segment, and you are overflowing stack memory (and hence getting a stack overflow).
The solution is to allocate that memory from a different place. I know in old Fortran it is possible to use COMMON blocks to statically allocate memory directly from your code segment. You still can't dynamically allocate more, so your subroutine can't be reentrant, but if your subroutine only gets called once at a time (which it appears to be) this may be the best solution.
A better solution would be to switch to Fortran 90 or newer and use the ALLOCATE keyword to dynamically allocate the arrays on the heap instead of the stack. Then you can allocate as large a chunk as your OS can give you, but you won't have to worry about overflowing the stack, since the memory will be coming from another place.
You may be able to fix this by changing it in the compiler, as M.S.B. suggests, but a better solution is to simply fix the code.
Does that compiler have an option to put arrays on the heap?
You could try a different compiler, such as one that is still supported. Fortran 95 compilers will compile FORTRAN 77. There are many choices, including open source. Intel Visual Fortran, the successor to Compaq Visual Fortran, has the heap option on Windows & Mac OS X for placing automatic and temporary arrays on the heap.
MELE is actually a larger array then NM: 10000 x 10000 x 4 x 4, versus 10001 x 100001 x 4 (supposing 4 byte numbers, as did Daniel) -- 1.49 GB versus 381 kB. MELE is declared in your main program and, from your tests, is acceptable, even though it is larger. So either adding NM pushes the memory usage over a limit (the total for these two arrays is 1.86 GB) or the difference in the declaration matters. The size of MELE is known at compile time, that of NM only at run time, so probably the compiler allocates the memory differently. Really in this program the size of NM is known, but in the subroutine the dimensions are received as arguments, so to the compiler the size is unknown. If you change this, the compiler may change how it allocates the memory for NM and the program may run. Don't pass the dimensions of NM as arguments -- make them constants. The elegant way would be to make an include file with three PARAMETER statements setting up the array sizes, then include that include file wherever needed. Quick and dirty, as a test, would be to repeat identical PARAMETER statements in the subroutine -- but then you have the same information twice, which has to be changed twice if you make changes. In either case, you have to remove the array dimensions from the subroutine arguments in both the call and subroutine declaration, or use different names, because the same variable in a subroutine can't be a parameter and an argument. If that doesn't work, declare NM in the main program and pass it as an argument to the subroutine.
Re the COMMON block -- the dimensions need to be known at compile time, and so can't be subroutine arguments -- same as above. As Daniel explained, putting the array into COMMON would definitely cause it not to be on the stack.
This is beyond the language standard -- how the compiler provides memory is an implementation detail, "under the hood". So the solution is partially guess work. The manual or help for the compiler might have answers, e.g., a heap allocation option.
Stack overflows related to array size is a warning sign that they are being pushed whole onto the call stack, instead of on the heap. Have you tried making the array variables allocatable? (I'm not sure if this is possible in F77, though)