bool subsetSum(int arr[], const int &n, const int &sum)
{
bool T[n + 1][sum + 1];
}
The above code is used to generate an 2d Boolean type array in subsetSum, but the compiler says both "n" and "sum" must be constant. How can I create an 2d array in my function just like ordinary stack variable like “double” and “int”?
Declaring an array like you are atempting is not standard C++. The sizes used to declare the array must be known at compile time. Hence, the compiler reports that as an error. Some compiles support variable length arrays (VLAs) as an extension but they are not standard C++.
For dynamic arrays like that, use std::vector.
std::vector<std::vector<bool>> T(n+1, std::vector<bool>(sum+1));
It takes away need to deal with dynamic memory allocation and deallocation from user code.
Related
There is a problem when I want to define a complex array:
#include<complex.h>
int main(){
int matrix=1000;
std::complex<double> y[matrix];
}
The error is "Variable length array of non-POD element type 'std::complex'
Is there something wrong with the definition of array here?
This kind of array only works with a length that is a constant expression, i.e. the length must be known at compile time.
To get a array of variable length, use an std::vector<std::complex<double>> y (matrix);
You should use std::vector (or std::array in some cases) over C-style arrays anyway.
You can't statically allocate a C++ array with size being a regular variable, since the value of matrix is not known until the program is executed. Try dynamically allocating your array:
std::complex<double> y = new std::complex<double>[matrix]
When you are doing using it, call:
delete[] y
The size of arrays must be know at compile time. It must be a constant expression. The value of matrix is only known at runtime. You must make matrix a constant to work.
const int matrix=1000;
The other way around is to use a vector whose size is variable and is initialized at runtime.
int matrix=1000;
std::vector<std::complex<double>> y(matrix);
C++ doesn't allow variable length arrays, either do it dynamically or use a vector.
Your compiler thinks that you are declaring a variable-length array, since matrix is non-const. Just make it constant and things should work:
const int matrix = 1000;
std::complex<double> y[matrix];
The error stems from the fact that variable-length arrays are only allowed for "dumb" data types, e.g. int/char/void* and structs, but not classes like std::complex.
double rainPerMonth(const int YEARS)
{
int monthYear[MONTHS][YEARS];
// ...
}
Visual Studio shows a squiggly line underneath the array declaration, saying that YEARS must be a constant when I'm creating the array. Is this an IDE issue because the variable has yet to be initialized, or am I writing this incorrectly?
MONTHS is already declared globally.
An array size must be a constant expression - that is, a value known at compile time. (Some compilers offer C-style variable-length arrays as a non-standard extension, but I don't think Visual C++ does. Even if it does, it's better not to rely on such extensions.)
A function argument isn't known at compile time, so can't be used as an array size. Your best option is here is probably
std::vector<std::array<int, MONTHS>> monthYear(YEARS);
In C++, an array must be sized at compile time. What you are attempting to do is declare one that is sized at runtime. In the function you've declared, YEARS is only constant within the scope of the function. You could call it rainPerMonth(someInt); where someInt is the result of some user input (which shows you that the result is not a compile-time constant).
Variable Length Arrays are an extension to C, but not C++. To do what you want, you can use dynamic memory, or a std::vector.
I think your problem lies in the fact that C++ wants a constant in the sense of compile-time constant to create your variable monthYear. If you pass it as a function, it need not be known at compile time? For example:
const int x=2;
const int y=3;
char xyChoice;
std::cin >> xyChoice;
if (xyChoice == 'x')
rainPerMonth(x);
else
rainPerMonth(y);
I'm unsure, but it seems to me like this would give you a constant int being passed to your function, but the compiler wouldn't know what size to create an array for before runtime?
I'm trying to do something like this:
const int array_size = 5;
string stuff[array_size];
My compiler won't let me compile this, even though array_size is a constant. Is there a way to do this without dealing with dynamic arrays?
Edit: "error C2057: expected constant expression"
I have answered this question assuming you are either coding in C or C++. If you are using a different language, this answer doesn't apply. However, you should update your question with the language you are trying to use.
Consider the following program:
int main () {
const int size = 5;
int x[size];
return 0;
}
This will compile in both C++ and C.99, but not C.89. In C.99, variable length arrays were introduced, and so locally scoped arrays can take on a size specified by a variable. However, arrays at file scope in C.99 cannot take a variable size parameter, and in C.89, all array definitions have to have a non variable size.
If you are using C.89, or defining a file scope array in C.99, you can use an enum to name your constant value. The enum can then be used to size the array definition. This is not necessary for C++ however, which allows a const integer type initialized by a literal to be used to size an array declaration.
enum { size = 5 };
int x[size];
int main () { return 0; }
#define array_size 5
string stuff[array_size];
You can use e.g. a vector or the new keyword to allocate memory dynamically, because declared arrays can not have runtime sizes.
Only thing I can think of is that you defined another array_size variable in your code, which is not a compile time constant and hides the original array_size.
array_size is not treated as a compile time constant. Constness added just makes sure that programmer can not modify it. If tried to modify accidentally, compiler will bring to your attention.
Size of an array needs to be a compile constant. Seems like your compiler is not supporting Variable Length Array. You can #define the size of the array instead which is treated as a constant expression.
#include<stdio.h>
using namespace std;
void fun(int** a){}
int main()
{
int n;
scanf("%d",&n);
int a[n][n];
fun(a);
return 0;
}
Getting this error in C++, but it is working fine in C
but working for typecasted to (void*)a
and then converting to array=(int**)a:
test_.cpp:9:8: error: cannot convert
‘int (*)[(((unsigned int)(((int)n) + -0x00000000000000001)) + 1)]’
to ‘int**’ for argument ‘1’ to ‘void fun(int**)’
tried to pass a[][size] but size is not known
Double arrays do NOT convert to double pointers.
Pass a double array to your function like so:
void fun(int arr[][5]);
Now it will work.
There are a couple of problems with your code. One is in C, the other, C++.
The C problem:
Even in C, your multidimensional array int a[n][n] does not convert to an int**. There's a huge difference between ragged (or jagged) multidimensional arrays and contiguous multidimensional arrays. Ragged arrays are declared and allocated as
int ** jagged_array
A jagged array declared in this style can obviously be passed as an int** argument to some function; there's no conversion involved. With this type of array, the programmer must allocate (and eventually free) storage for an array of int* pointers to each of the rows in the array and must also allocate (and eventually free) storage for each of the array's rows.
int * jagged_array[size_spec].
A jagged array declared in this style can also be passed as an int** argument to some function because of the way arrays decay to pointers in C (and C++). With this type of array, the programmer must allocate (and eventually free) storage for each of the array's rows.
Note that in both forms, there is an explicit place in memory for the int* pointers that point to the zeroth elements of the rows of the array. That is not the case with multidimensional arrays. A pointer to a row in a multidimensional array is computed, not stored. A multidimensional array declared as int a[n][n] cannot decay to an int**. It instead decays into an int*[n]. In C, a function that receives a variable length multidimensional array such as your int a[n][n] should be declared as <return_type> fund (int n, int vla[n][n]). (The array argument could also be specified as vla[][n]; the outer dimension is not needed.)
The C++ problem:
You are using variable length arrays. C++ does not support that C99 concept. That concept didn't exist in C with the original 1998 version of C++. The 2003 C++ standard was a minor revision to the 1998 C++ standard, so it didn't jump to C99. The authors of the most recent C++ standard, C++11, explicitly rejected supporting those C99 variable length arrays. You can't use variable length arrays in C++, at least not portably.
When T[N][N] decays it turns into T*[N] for which there is no viable conversion when passing in the array.
You have to specify the second dimension size when passing 2D array to functions. Otherwise, compilers cannot do addressing on the 2D array elements without knowing the size of second dimension.
Use
f(a[][5])
I know that int* array = new int [n]; allocates memory space in heap.
But if I declare something like that: int array[n]; in codeblocks it compile successfully, but if I move it to visual studio, it comes out of error.
What I want to ask is:
What does int[n] really do and how does it compare to heap allocation? What is the difference between them?
What the error may come out if I use int array[n] instead of int* array = new int [n];?
int array[n] declares an array on the stack, not the heap. In standard C++ n must be a compile time constant, however some compilers have an extension that allows for variable length arrays declared in this form without a compile time constant n. It's not standard and probably shouldn't be used.
int array[n] can cause a couple problems over int* array = new int [n];:
If n is big enough you can cause a stack overflow. Or if the array is a class member and you create a large array of the class.
If array is a class member moving could be as expensive as copying
If array is a class member and you have given out pointers to the array and move the class, the pointers now refer to a post-moved object, or if random memory if the object was also destroyed. Either way, bad.
GCC has an extension in C++ that allows int array[n] where n is not a compile time constant value. The standard language doesn't allow you to use non-constant value for n in such a case (it is allowed in C99).
If I understand your questions correctly, then I can answer both.
int array[10] is allocated on the stack, whereas int *array = new int[10] is allocated on the heap. Usually, stack arrays only work with a constant number of elements, so int array[n] is not allowed in C90 (as long as n is not constant).
MinGW (which is the version of the GCC compiler that codeblocks uses on windows) has an extension which does allow you to write int array[n] in C90 mode, where n is not constant. Visual C++ does not allow this.
when you write int array[n], that means you are performing a static allocation. i.e. memory will be allocated at the compile time. So using a variable length here will result in a compile time error.