int m,n;
cin>>m>>n;
int A[m][n];
Question is: Will array A get memory on stack or heap in C++ ?
Edit: I know using new is a better route.
This technique works in my mingw g++ compiler. I am just curious.
This behaviour depends on the particular compiler and is not part of the standard.
In gcc, which mingw is a port of, the memory for automatic variables as such, including variable lengths arrays is allocated on the stack.
According to the gcc manual:
6.19 Arrays of Variable Length
[...] These arrays are declared like any other automatic arrays, but with a
length that is not a constant expression. The storage is allocated at
the point of declaration and deallocated when the block scope
containing the declaration exits. [...] You can use the function alloca to get an effect much like variable-length arrays.
Ref: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
According to man 3 alloca:
The space allocated by alloca() is allocated within the stack frame
Please keep in mind that:
ISO C++ forbids variable length arrays
Alternatively you can allocate your array dynamically (with new) or preferably use the C++ containers anyway where possible.
Edit: Added note on variable behaviour between compilers, based on Paul's comment.
Related
This question already has answers here:
How does GCC implement variable-length arrays?
(2 answers)
Closed 1 year ago.
How does this example compile and run?
#include <iostream>
int main() {
int input;
std::cin >> input;
int arr[input];
return 0;
}
My understanding is that since the input's value is not known during compile time, it'd have to be a heap allocated array. Isn't the stack space for things like arrays (without allocating on the heap) allocated when the program starts?
My understanding is that since the input's value is not known during compile time, it'd have to be a heap allocated array.
While the C++ language rules do indeed say that you can’t do this, from a technical perspective about how the call stack is typically implemented this actually isn’t necessarily true. Generally, yes, objects that don’t have a size known in advance aren’t put on the stack. However, in the case of a local variable that’s an array of variable length, it’s not that hard for the compiler to put that array in stack space. For example, the C language supports this, and this older question addresses one way of implementing it. Even though C++ doesn’t allow for variable-length arrays the way C does (technically speaking what you have here isn’t legal C++ code), some compilers allow for it.
Isn't the stack space for things like arrays (without allocating on the heap) allocated when the program starts?
This usually isn’t the case. When the program starts up, it’s allocated a region of memory and told “this is where your stack should go,” but that space is typically not determined by anything about how the program is written and is usually controlled by the OS or set by the compiler. Then, whenever space on the stack is needed - say, because a function is called or because a new block scope is entered - the program takes up some space on the call stack, handing it back when the block scope exits or the function returns.
As a result, the program doesn’t need to know at the point where it starts how much space to reserve on the stack for each function. It can defer that until the actual functions are called.
My understanding is that since the input's value is not known during compile time, it'd have to be a heap allocated array.
Your understanding is correct.
Isn't the stack space for things like arrays (without allocating on the heap) allocated when the program starts?
In practice, the memory for execution stack is typically allocated when the program starts. This isn't something specified by the C++ language, but is an implementation detail.
How does this example compile and run?
The program is ill-formed. Compilers aren't required to compile the program and are require to diagnose the problem (if it doesn't diagnose it, then the compiler doesn't conform to the C++ standard). A compiler may still compile the program as a language extension. How that happens isn't specified by the C++ language.
I'm a beginning C++ programmer. So, I just learned that gcc has an extension that allows variably sized array without having to dynamically allocate memory. I want to know if this variably sized array is allocated in the stack or heap.
Conceptually it's allocated with automatic storage duration, so in terms of implementation, you can think of it as being on the stack.
Do consider using std::vector as an alternative though as that's standard and therefore portable C++.
The variable sized array is allocated in the stack.
VLA's are not supported by the C++ standard, although some compilers such as GCC do have them as an extension.
std::vector <> VLA in the GCC implementation.
std::vector is resizable and allocates memory on the heap.
VLA is not resizable, is limited by the maximum stack size and doesn't allocate memory.
So there is a flexibility difference, and there can be a performance difference especially if the array creation happens regularly (such as in a tight loop).
That said, some of these differences can sometimes be mitigated by for example, moving the 'array' outside of loops etc
Dynamic memory allocation in C/C++ happens through malloc and the static memory allocation ex: int a[3]; its allocated after the code is executed.
But this code int x[y+1]; only can happen after a value is attributed to y and this happens in execution time, so its static, dynamic or both? does the compiler insert a malloc in the machine code automatically?
It is a Variable Length Array (VLA). Wikipedia: http://en.wikipedia.org/wiki/Variable-length_array
Technically, it is not legal in C++, but compilers often support it as an extension, but generate warnings when they are turned on. See
Why aren't variable-length arrays part of the C++ standard?
It is legal in C.
int[] is on the stack, while malloc'd or new'd things are on the heap.
VERY basically int[] gets allocated automatically when it is reached (where y is already known) and gets dropped when it gets out of scope. It is not everything already allocated at startup.
There are no hidden malloc calls or stuff, that is just how the stack memory works.
(I hope for an answer from someone who actually knows C/C++)
in which cases should I use the keyword new to allocate array when the size is a variable? I am reading this code: https://github.com/Hawstein/cracking-the-coding-interview/blob/master/1.7.cpp
In the function zero(), why row[m] and col[n] declarations doesn't cause errors? The m and n are function variables.
Thanks
VLA - variable length arrays are a nonstandard extension of the C++ language, thus your code can only be compiled with a compiler extension
You should use dynamic allocated memory in every case when you don't know in advance the size of the array and you don't want/can't waste precious stack memory allocating a temporary or, even better if that works for you, use a std::vector (a vector uses heap memory anyway for its elements)
Edit: Another important suggestion is to take a look at smart pointers which can often offer additional advantages over raw pointers
Never.
Modern c++ compilers can handle variables for array sizes. They just use the values currently in m and n. There is no need to use new.
int main(){
int size;
cin >> size;
int myArray[size];
return 0;
}
Is myArray allocated on the stack? How so, if its size is unknown at compile time?
As an aside, is it possible to allocate a dynamically sized array on the stack?
These maybe bad practices but I'm asking if its allowed, not if its good practice or not.
Yes, where/when this is allowed (it's not actually allowed in C++, though gcc allows it as an extension) myArray will be allocated on the stack. The implementation is pretty simple: choose the size and subtract it from the stack pointer.
As mentioned, C++ doesn't currently allow this, but a proposal for a dynarray class that will allow it has been accepted into the working paper for C++ 14, so something similar will (probably) be allowed soon (if your compiler doesn't already -- some may easily do so, though I've never tested for it).
Yes, it's perfectly possible, though as it's been just pointed out this is only available in ISO C99 and as a GCC extension in C++. If I may quote from the GNU website:
Variable-length automatic arrays are allowed in ISO C99, and as an
extension GCC accepts them in C90 mode and in C++. These arrays are
declared like any other automatic arrays, but with a length that is
not a constant expression.
It looks (cin) like you want to use C++. If so, perhaps you should use std::vector.
To set the size, yes, on the stack, see
How to set initial size of std::vector?