declare dynamic array in function - 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.

Related

When an array is declared normally, is the memory allocated statically, dynamically or otherwise?

For example if an integer array is declared:
int ar[12];
And here a vector of integers:
vector<int> ar; //OR
vector<int> ar(12);
In either case, is memory allocated to the array at compile time or runtime? I know that vector class in C++ STL uses dynamic memory allocation but what about the ordinary array? Also:
int n;
cin >> n;
char ar[n];
If memory allocation is at compile time then how does this work? I can't find anything scavenging the net.
"Normal" arrays will have a size known at compile-time, which means the compiler can (and will) make sure that there's space for them. That space might not be allocated inside the executable program but allocated at run-time (like e.g. a local variable inside a function).
The size of a vector is unknown at compile-time, and its the vectors constructor that will allocate memory (if asked to, as in the case with vector<int> ar(12);). The memory for vectors will always be allocated dynamically of the heap.
Then there's also std::array which is a C++ standard container around a compile-time array. When it comes to size and allocations it acts like a "normal" array, but since it's also a standard container object it can be used with functions and algorithms designed for those.
And to confuse matter even more, something being "static" has a special meaning in C++, so saying than an array is "statically" allocated could mean different things depending one ones viewpoint. However, "statically allocated" seems to be commonly used for things like arrays, whose memory is allocated and handled by the compiler and its generated code.

Are dynamic arrays actually dynamic?

I'm reading about dynamic arrays (specifically at https://www.learncpp.com/cpp-tutorial/dynamically-allocating-arrays/), and it seems to me that dynamic arrays are not actually dynamic, in that the size allocated for them cannot be changed.
If I am understanding correctly, the main use or point of dynamic arrays vs fixed arrays is that dynamic arrays will be allocated on the heap rather than the stack, and therefore can be larger. The terms "dynamic" and "fixed" give me the impression that one can be changed and the other cannot, but it doesn't seem to be the case.
Is this correct, or am I misunderstanding something about dynamic vs fixed arrays?
Dynamic arrays are dynamic i.e. they have dynamic lifetime / dynamic storage (i.e. they are stored in free store aka "heap").
Dynamic arrays are also dynamic in the sense that unlike array variables, their size can be determined at runtime i.e. it doesn't need to be compile time constant. Example:
int size;
std::cin >> size;
auto ptr = std::make_unique<int[]>(size); // dynamic
int arr[size]; // ill-formed
You're correct in that the size of a (dynamic) array cannot change through its lifetime. Thus, a dynamic array in C++ isn't the abstract data structure by the same name, also known by names "growable array", "resizable array", "dynamic table", "mutable array", or "array list". The C++ standard library has implementation of that data structure by the name std::vector.
"Dynamic" refers not to size, but to allocation method. In most C++ implementations there's several methods of storing data, but the two relevant here are local, as in on the stack, and dynamic, as in on the heap.
Dynamic tends to mean "allocated with new" or a similar mechanism, while stack allocations happen implicitly.
X* x = new X[20]; // "Dynamic" array
X x[20]; // Local array
Neither of these can be easily resized.
A dynamic array can be reallocated and resized, while a stack one cannot, the size on the stack is fixed. This makes dynamic arrays more flexible in that regard, but it's not something that comes for free, you need to do a lot of work to implement that to ensure that your newly allocated object is consistent and that all pointers to it have been updated.
Additionally, the lifetime is different, as dynamically allocated structures have an indefinite lifetime, as the programmer you control that, while local variables have a scope-defined lifetime that is non-negotiable. When you exit the scope, they're gone.
Dynamic allocations come with considerable overhead on the part of the programmer, you're responsible for managing that lifecycle or delegating it to a wrapper that can do it for you, like a smart pointer.
In modern C++ using actual low-level arrays is difficult and error-prone which is why std::vector is typically used instead. It provides way more guarantees and helps manage lifecycles for you if used effectively. The implementation of these manages resizing, and object deletion for you.

dynamic array declaration in c++

I have seen two ways to declare a dynamic array in C++. One is by the use of new operator:
int *arr = new int [size];
and other is directly declaring:
int arr[size];
NOTE: Here note that size is a variable whose value will be provided by the user at runtime.
Question is what is the best approach to declare a dynamic array in C++?
Assuming your question is, "what is better?".
The second, the direct creation of the array, creates the array on the stack, the first on the heap. The second is called variadic-length-array (VLA), which is nonstandard C++ and not portable, but in C it is standard. The GNU C++ compilers support that, but others do not support that. Internally the array is allocated as with alloca(POSIX)/__builtin_alloca(GNU), which extends the stackframe. The variadic-length-array can smash your stack with a big size (maybe produces a SIGSEGV, but may also corrupt other data), while the new-operator throws a catchable exception. (However, using recursive functions can smash your stack the same way...). It is not a bad practice to use VLAs, when you know the size is relatively small. The VLAs can even improve the performance, when the array needs to be allocated multiple times (the allocation of the VLA is faster than the allocation on the heap). Because of the VLA living on the stack it doesn't need to be freed/deleted, it is automaticly freed when the function quits.
This applies to the GNU-Compilers: VLAs do call the destructors on destruction, but the memory allocated with alloca/__builtin_alloca is just going to be freed at the end of the function as memory (allocated with malloc) freed with free.
As conclusion, I think the allocation with the new is better for most problems. But the VLA is good for fast memory allocation local in a function. There is no portable approach to return a VLA from a function (without hacking through assembly) (You can return arrays with constant size from a function, however it needs to be specified in the signature). For this, there is std::array and std::vector, I recommend to use that instead of hand made memory management (the allocation with new and delete or Cs malloc and free), which is not freed when an exception is raised. Memory-management should always be nested in the constructor and destructor of a class, if you need to use such functions. The destructors are always called, when the object goes out of scope, so there are no memory leaks.
One thing you cannot do with VLAs and new/delete is fast resizing. Even std::vector does not use it. It is done with the C-function realloc, which tries to keep the buffer inplace. When you need this you can easily design a std::vector-like class, which should call free in the destructor. To destruct an element you call element.~T(), where T is the type of element.
However std::vector tries to improve the performance of resizing by allocating a buffer with additional space.
The main difference between the two methods is that the first allocates memory from the Free-store(Heap), the second one allocates from the stack. In fact the second one is not good to use because the stack memory is very limited in space compared to the heap. Also the first statement obviously returns a pointer to the first element in the allocated memory while the second one returns the array itself.

Variable lengthed array in gcc

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

How to create a C-style array without calling default constructors?

I am writing a memory-managing template class in which I want to create a C-style array of fixed size, to serve as a heap. I keep the objects stored in an array like this:
T v[SIZE];
As this only serves the role as a heap that can hold T objects, I don't want the T default constructor to get automatically called for every object in the array.
I thought about the solution to define the heap like this:
char v[SIZE * sizeof(T)];
...but this will give me alignment problems.
Is there any better way to achieve this?
ADD: As I have special run time requirements, it is essential that this class doesn't do any allocations on the global heap.
ADD 2: SIZE is a template argument and known at compile-time.
The standard containers use allocators to seperate allocation/deallocation from construction/destruction. The standard library supplies a single allocator which allocates on the heap.
This code declares an array big enough to hold SIZE elements of type T with the correct allignment:
typedef typename std::tr1::aligned_storage<sizeof(T),std::tr1::alignment_of<T>::value>::type aligned_storage;
aligned_storage array[SIZE];
The solution using std::allocator can't be used to declare an array on the stack, and as the standard containers require that custom allocators hold no state, a custom allocator can't be portably used to allocate on the stack either.
If your compiler doesn't support std::tr1::alignment_of you can use boost::alignment_of instead.
What you are looking for is called an Allocator. A good overview can be found here: http://www.codeproject.com/KB/cpp/allocator.aspx
What I'd probably do is create an array of char (about like you've already considered), but allocate enough space for one more object than you really need. You'll then need to write a bit of code to find the correct alignment for your objects in that space.
The largest alignment requirement for an object is its own size (otherwise arrays of those objects couldn't be contiguous, which is required). Therefore, you pick the first address in the char-buffer that's a multiple of sizeof(T), and start your array from there.
Weird, but should work:
long long v[size * sizeof(T)/sizeof(long long)+1];
This buffer will be alligned on 64 bits.
But better will be allocate memory by new.
In any case, if size is variable - compiller will allocate memory dynamically through malloc/new (and not on stack).
EDIT: You can't use std::auto_ptr to automaticaly free buffer. Instead scoped_arr from boost can be used
You can use a struct to handle the alignment issue.
struct Tbuffer { char data_[ sizeof( T ) ]; }
struct Tbuffer heap[ SIZE ];
How I probably will do it (after looking on EASTL fixed_vector implementation):
PRAGMA_PRE_ALIGN(sizeof(T)) char[SIZE * sizeof(T)]; PRAGMA_POST_ALIGN(sizeof(T))
...and implement compiler specific PRAGMA_PRE_ALIGN and PRAGMA_POST_ALIGN macros, that insert the correct #pragmas.
Unfortunately, boost and tr1 are not possible for this project.