I am learning C++ and I just read about dynamic arrays and how it lets you set the length of an array during runtime rather than during compile time. However, you don't need a dynamic array to do this. So what is the point of a dynamic array; when would you use it? I feel like I am missing something obvious so any insight is much appreciated. Thanks!
// Static binding.
int size = 0;
cout << "Enter size of array:" << endl;
cin >> size;
int array[size];
int array_length = sizeof(array) / sizeof(int);
cout << "Number of elements in array: " << array_length << endl;
// I just set the length of an array dynamically without using a dynamic array.
// So whats the point of a dynamic array then?
I don't think you can do that in C++. Only C99 allows variable-length arrays.
Does this even compile? Were you talking about the vector class?
EDIT:
It does not compile in Visual Studio 2010:
1>..\main.c(207): error C2057: expected constant expression
1>..\main.c(207): error C2466: cannot allocate an array of constant size 0
1>..\main.c(207): error C2133: 'array' : unknown size
1>..\main.c(209): error C2070: 'int []': illegal sizeof operand
You would need a dynamically allocated array for cases where you don't know ahead of time how many items you will have.
Another (and better) option is to use std::vector.
As per the standard, an array defined "statically" would:
have a constant size, defined at compile time
Be allocated on the stack rather than the heap.
So the reasons you'd opt for a dynamically allocated array (using new type[]) are because you don't always know the size you need for an array at compile time, and the stack is a limited resource that you often need to be careful not to exhaust.
But in practical terms, you'd often be best served by using std::vector or other STL container instead of a builtin array of any sort.
Your example would not compile under a standards-compliant compiler. For instance, GCC says this:
http://codepad.org/Kvq2PfNx
In function 'int main()':
Line 13: error: ISO C++ forbids variable-size array 'array'
compilation terminated due to -Wfatal-errors.
There is a way of dynamically allocating stack memory using the alloca function. However, this memory is invalidated when the function terminates. You should generally prefer new[]/delete[] or std::vector for dynamic memory allocation.
You can dynamically create an array using the keyword new..
Lets say you don't know ahead of time how many values you need. It's a waste of space to declare an array a[100] when the user might just enter a few values. Also the user might enter more values, and then you would have a array overflow error.
You can create an array dynamically like - int a = new int[]
Also, statically created arrays are created on the stack where as dynamically created arrays are created on the heap-which means the memory is globally available even after the function goes out of scope.
Related
This question already has answers here:
How do I find the length of an array?
(30 answers)
Closed 8 years ago.
I have this code.
int x[5];
printf("%d\n",sizeof(x) );
int *a;
a = new int[3];
printf("%d\n",sizeof(*a));
When I pass a 'static' array to sizeof(), it returns the dimension of the declared array multiplied by the number of bytes that the datatype uses in memory. However, a dynamic array seems to be different. My question is what should I do to get the size of an 'dynamic' array?
PD: Could it be related to the following?
int *a;
a=new int[3];
a[0]=3;
a[1]=4;
a[2]=5;
a[3]=6;
Why can I modify the third position if it's supposed I put a 'limit' in "a=new int[3]".
When I pass a 'static' array to sizeof(), it returns the dimension of the declared array multiplied by the number of bytes that the datatype uses in memory.
Correct, that is how the size of the entire array is computed.
However, a dynamic array seems to be different.
This is because you are not passing a dynamic array; you are passing a pointer. Pointer is a data type with the size independent of the size of the block of memory to which it may point, hence you always get a constant value. When you allocate memory for your dynamically sized memory block, you need to store the size of allocation for future reference:
size_t count = 123; // <<== You can compute this count dynamically
int *array = new int[count];
cout << "Array size: " << (sizeof(*array) * count) << endl;
C++14 will have variable-length arrays. These arrays will provide a proper size when you check sizeof.
Could it be related to the following? [...]
No, it is unrelated. Your code snippet shows undefined behavior (writing past the end of the allocated block of memory), meaning that your code is invalid. It could crash right away, lead to a crash later on, or exhibit other arbitrary behavior.
In C++ arrays do not have any intrinsic size at runtime.
At compile time one can use sizeof as you showed in order to obtain the size known to the compiler, but if the actual size is not known until runtime then it is the responsibility of the program to keep track of the length.
Two popular strategies are:
Keep a separate variable that contains the current length of the array.
Add an extra element to the end of the array that contains some sort of marker value that indicates that it's the last element. For example, if your array is known to be only of positive integers then you could use -1 as your marker.
If you do not keep track of the end of your array and you write beyond what you allocated then you risk overwriting other data stored adjacent to the array in memory, which could cause crashes or other undefined behavior.
Other languages tend to use the former strategy and provide a mechanism for obtaining the current record of the length. Some languages also allow the array to be dynamically resized after it's created, which usually involves creating a new array and copying over all of the data before destroying the original.
The vector type in the standard library provides an abstraction over arrays that can be more convenient when the size of the data is not known until runtime. It keeps track of the current array size, and allows the array to grow later. For example:
#include <vector>
int main() {
std::vector<int> a;
a.push_back(3);
a.push_back(4);
a.push_back(5);
a.push_back(6);
printf("%d\n", a.size());
return 0;
}
As a side-note, since a.size() (and sizeof(...)) returns a size_t, which isn't necessarily the same size as an int (though it happens to be on some platforms), using printf with %d is not portable. Instead, one can use iostream, which is also more idiomatic C++:
#include <iostream>
std::cout << a.size() << '\n';
You do not, at least not in standard C++. You have to keep track of it yourself, use an alternative to raw pointers such as std::vector that keeps track of the allocated size for you, or use a non-standard function such as _msize https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/msize?view=msvc-160 on Microsoft Windows or malloc_size https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/malloc_size.3.html on MacOS X.
What is the difference between this two array definitions and which one is more correct and why?
#include <stdio.h>
#define SIZE 20
int main() {
// definition method 1:
int a[SIZE];
// end definition method 1.
// defintion method 2:
int n;
scanf("%d", &n);
int b[n];
// end definition method 2.
return 0;
}
I know if we read size, variable n, from stdin, it's more correct to define our (block of memory we'll be using) array as a pointer and use stdlib.h and array = malloc(n * sizeof(int)), rather than decalring it as int array[n], but again why?
It's not "more correct" or "less correct". It either is xor isn't correct. In particular, this works in C, but not in C++.
You are declaring dynamic arrays. Better way to declare Dynamic arrays as
int *arr; // int * type is just for simplicity
arr = malloc(n*sizeof(int*));
this is because variable length arrays are only allowed in C99 and you can't use this in c89/90.
In (pre-C99) C and C++, all types are statically sized. This means that arrays must be declared with a size that is both constant and known to the compiler.
Now, many C++ compilers offer dynamically sized arrays as a nonstandard extension, and C99 explicitly permits them. So int b[n] will most likely work if you try it. But in some cases, it will not, and the compiler is not wrong in those cases.
If you know SIZE at compile-time:
int ar[SIZE];
If you don't:
std::vector<int> ar;
I don't want to see malloc anywhere in your C++ code. However, you are fundamentally correct and for C that's just what you'd do:
int* ptr = malloc(sizeof(int) * SIZE);
/* ... */
free(ptr);
Variable-length arrays are a GCC extension that allow you to do:
int ar[n];
but I've had issues where VLAs were disabled but GCC didn't successfully detect that I was trying to use them. Chaos ensues. Just avoid it.
Q1 : First definition is the static array declaration. Perfectly correct.
It is when you have the size known, so no comparison with VLA or malloc().
Q2 : Which is better when taking size as an input from the user : VLA or malloc .
VLA : They are limited by the environment's bounds on the size of automatic
allocation. And automatic variables are usually allocated on the stack which is relatively
small.The limitation is platform specific.Also, this is in c99 and above only.Some ease of use while declaring multidimensional arrays is obtained by VLA.
Malloc : Allocates from the heap.So, for large size is definitely better.For, multidimensional arrays pointers are involved so a bit complex implementataion.
Check http://bytes.com/topic/c/answers/578354-vla-feature-c99-vs-malloc
I think that metod1 could be little bit faster, but both of them are correct in C.
In C++ first will work, but if you want to use a second you should use:
int size = 5;
int * array = new int[size];
and remember to delete it:
delete [] array;
I think it gives you more option to use while coding.
If you use malloc or other dynamic allocation to get a pointer. You will use like p+n..., but if you use array, you could use array[n]. Also, while define pointer, you need to free it; but array does not need to free.
And in C++, we could define user-defined class to do such things, and in STL, there is std::vector which do the array-things, and much more.
Both are correct. the declaration you use depends on your code.
The first declaration i.e. int a[size]; creates an array with a fixed size of 20 elements.
It is helpful when you know the exact size of the array that will be used in the code. for example, you are generating
table of a number n up till its 20th multiple.
The second declaration allows you to make an array of the size that you desire.
It is helpful when you will need an array of different sizes, each time the code is executed for example, you want to generate the fibonacci series till n. In that case, the size of the array must be n for each value of n. So say you have n = 5, in this case int a [20] will waste memory because only the first five slots will be used for the fibonacci series and the rest will be empty. Similarly if n = 25 then your array int a[20] will become too small.
The difference if you define array using malloc is that, you can pass the size of array dynamically i.e at run time. You input a value your program has during run time.
One more difference is that arrays created using malloc are allocated space on heap. So they are preserved across function calls unlike static arrays.
example-
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n;
int *a;
scanf("%d",&n);
a=(int *)malloc(n*sizeof(int));
return 0;
}
I am getting the error
"The expression needs to be a constant"
when I try to do this:
float mat1[m_Floats.size()][iNumClass];
Can I trick the compiler (VS2010) into compiling this anyway?
No. Only C99 specify dynamic array allocation (i.e. where size is known only at compile time). Maybe there is a MSVC extension to the standard, but you should go the canonical way in creating the array of pointers and each float subarray using new, like in:
float **mat1 = new float*[m_Floats.size()];
for (int i = 0; i < m_Floats.size(); ++i) {
mat1[i] = new float[iNumClass];
}
well, instead of "tricking the compiler", you can dynamically allocate your matrix with the operator new
No. The size of a declared array needs to be known at compile time. The value of m_Floats.size() depends on how many members are in that object.
If you need to allocate arrays with variable size, you'll need to handle it yourself with new or some appropriate classes/methods that encapsulate that for you.
I'm trying to create an object array and it works just fine if I enter the array size manually, but whenever it tries to get the infromation from the function args it gives the errors "Expected constant expression" and "cannot allocate an array of constant size 0".
I've searched around and found multiple solutions but none of them works for me. Code currently looks like this:
Array::Array(int in, int min, int max)
{
size = in;
Heltal *htal[size];
}
The size integer and htal object is defined in the header file.
The line that seems to be causing the problem is the last one.
Whats causing this and how do I fix it?
VLAs (variable length arrays) are not supported in C++. Even if they were, a is a vector so Heltal *htal[a]; doesn't make sense.
You fix this by using an std::vector instead of an array (of a valid size):
std::vector<Heltal*> htal(a.size() /*or whatever size you want*/);
The size of an array has to be a compile-time constant, and size isn't a constant. You'll need to dynamically allocate the array instead:
std::vector<Heltal *> htal(size);
Is there any way of creating a static array in c++ at run time.
What i want is really simple like just want to get input number from user and create a static array of size of input number at run time. No new operator is required no pointer are required just static array?
No. static variable is allocated before the program code is actually running (i.e.: before your main is called). What you need is a dynamic (aka created at run time) array. If you want to avoid new you can create it on stack (by passing parameter to a function that will create it and working on it within that function), but that's not the same as static. You can also use template containers that will do the allocation and resizing for you (like std::vector, mentioned in other answers)
edit
It seems to bother some people that I didn't mention the matter of initializing static objects. Although not directly relevant to the question - worth to know that static member variables or static variables within a scope can be initialized at run time, but the space for them is reserved prior to the main, so the size of the variable cannot be changed.
If you mean
unsigned size;
std::cin >> size;
int arr[size];
Then: No. C99 has a feature called Variable-Length-Arrays, but the C++03 (and '0x) standard have no notion of this kind of feature.
Use alloca to allocate space on the stack, just like a static array or like a C99 variable length array.
#include <iostream>
#include <alloca.h>
int main() {
unsigned sz;
std :: cin >> sz;
int * p = static_cast<int*>(alloca(sz * sizeof(int)));
// do stuff with p, do not attempt to free() it
}
I've only ever used it with C, but it works well. Read about it first though. It probably isn't very portable.
No.
By definition, you need to dynamically allocate anything whose size is not known until runtime. That's why new and friends exist.
What does it mean to you that an array is static? What advantages do you think it gives you?
Actually, any static variable (including arrays) has its storage reserved at the beginning of the program. For this reason, its size has to be known before the program starts running, so it can't depend on user input in any way.
There are a number of ways to make dynamic non-static arrays, however, so let us know what you're trying to do.
It sounds like what you want is an array whose size is run-time defined but whose life time is defined by static storage duration (ie the length of the program).
You can not use the basic array built into the language. The size of these objects are defined at compile time and can not be modified at run-time. But there are a couple of alternatives.
The basic std::vector is probably what you want:
std::vector<int> data;
int main()
{
int size;
std::cout << "Input the size of the array\n";
std::cin >> size;
// This line sets the size of the container
// vector is basically a C++ wrapper around a dynamically sized array
data.resize(size);
// Now we can safely read values into the array (like) container.
for(int loop =0;loop < size;++loop)
{
std::cout << "Input Value " << loop << "\n";
std::cin >> data[loop];
}
}