Hello first thing first forgives me if I have mistakes in my English, I am beginner in c++ and I need help with this problem please
//global variables
int RangeOfArray;
int arr[RangeOfArray-1]; // error: array bound is not an integer constant before ']' token
void functionOne(){} // I need to access the array here.
void functionTwo(){} // as well here.
int main (){
cout<<"Type the length number of the array : ";
cin >> RangeOfArray;`
}
As you can see I need the array (arr) everywhere in my program but I can't why? I don't know
An array needs a size that can be known at compile time. RangeOfArray is not known at compile time. Also, you are declaring the array and then trying to assign a size to it, which is not possible. You'll need dynamic arrays for this purpose:
#include <iostream>
int RangeOfArray;
int* arr;
int main() {
std::cout << "Type the length number of the array : ";
std::cin >> RangeOfArray;
arr = new int[RangeOfArray];
}
..or preferably, std::vector:
#include <iostream>
#include <vector>
int main() {
std::cout << "Type the length number of the array : ";
int vec_size; std::cin >> vec_size;
std::vector<int> vec;
vec.resize(vec_size);
}
Any of the 2 options work.
In these declarations
//global variables
int RangeOfArray;
int arr[RangeOfArray-1]; // error: array bound is not an integer constant before ']' token
there is declared the global variable RangeOfArray that is implicitly initialized by zero and then there is declared the variable length array arr with the size -1 that is implicitly converted to the maximum value of the type size_t due to the usual arithmetic conversions because in C++ an expression that specifies a size of an array in its declaration is converted to the type size_t.
For starters variable length arrays is not a standard C++ feature. And moreover you may not declare a variable length array with static storage duration.
And secondly using the expression -1 as the size of an array does not make a sense.
If you need a global variable that simulates an array then use the standard container std::vector<int>.
For example
#include <iostream>
#include <vector>
//global variables
std::vector<int> arr;
void functionOne(){ /* ... */ } // I need to access the array here.
void functionTwo(){ /* ... */ } // as well here.
int main()
{
size_t RangeOfArray;
std::cout<<"Type the length number of the array : ";
std::cin >> RangeOfArray;`
arr.resize( RangeOfArray );
//...
}
The vector provides member function size that reports the current number of elements stored in the vector. So you need not to make the variable RangeOfArray global.
Pay attention to that it is not a good idea to use global variables.
So you could declare the vector in main and pass it by reference to functions where it is required.
why [I cannot use the array]?
The error message that you quoted explains why:
error: array bound is not an integer constant before ']' token
The size of an array must be compile time constant. RangeOfArray-1 is not compile time constant. Hence it cannot be used as the size of an array.
If you want to create an array whose size is determined at runtime, you must use dynamic storage. Simplest solution is to use std::vector from the standard library.
Another issue is that you try to use the variable before it has been assigned a value (although it has been zero-initialised). That approach doesn't work in imperative programming languages such as C++. You must assign a value before you can access it.
Mistake 1
In standard C++, the size of an array must be a compile time constant. So when you wrote:
int RangeOfArray;
int arr[RangeOfArray-1]; //not standard c++
The statement int arr[RangeOfArray-1]; is not standard C++ since RangeOfArray - 1 is not a constant expression.
Mistake 2
From Array declarators documentation:
If the expression is a constant expression, it shall have a value greater than zero.
This means even if RangeOfArray was a constant expression, due to static initialization, RangeOfArray will be initialized with 0 and so the expression RangeOfArray - 1 evaluates to the negative integer -1. And according to the above quoted statement, int[-1]; isn't valid.
Solution
Better would be to use std::vector as shown below:
#include <iostream>
#include<vector>
//global variables
std::vector<int> arr; // empty vector
void functionOne(){
std::cout<<"functionOne called with: "<<arr.size()<<std::endl;
}
void functionTwo(){
std::cout<<"functionTwo called with: "<<arr.size()<<std::endl;
}
int main (){
int RangeOfArray = 0;
std::cout<<"Type the length number of the array : ";
std::cin >> RangeOfArray;
//resize the vector named arr
arr.resize(RangeOfArray);
//call functionOne
functionOne();
//call functionTwo
functionTwo();
}
Related
I'm trying to create an array and the size of the array depends on the user input. But there is an error in my code, It said: "expression must have a constant value".
Here is my code:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int var;
cout << "What size do you want to choose: "<< endl;
cin >> var;
int arr[var];
}
How can I change my code and make it work?
How can I change my code and make it work?
Change
int arr[var];
to
std::vector<int> arr(var);
This will require #include <vector>
The syntax you are using is known as a "variable length array", and is NON-STANDARD. Only a few compilers support it as an vendor-specific extension to the C++ language.
A standard compliant fixed-length array must have its size known to the compiler as a compile-time constant.
For what you want, you need to use the new[] operator instead:
int *arr = new int[var];
...
delete[] arr;
Or better, use a std::vector container:
#include <vector>
std::vector<int> arr(var);
To allocate an array dynamically, we use the array form of new and delete (often called new[] and delete[]):
#include <iostream>
int main()
{
std::cout << "Enter a positive integer: ";
int length{};
std::cin >> length;
int *array{ new int[length]{} }; // use array new. Note that length does not need to be constant!
std::cout << "I just allocated an array of integers of length " << length << '\n';
array[0] = 5; // set element 0 to value 5
delete[] array; // use array delete to deallocate array
// we don't need to set array to nullptr/0 here because it's going to go out of scope immediately after this anyway
return 0;
}
Arrays in C++ must have constant size known at compile-time. You can preallocate several constant sizes known at compile time and offer the user to choose one of them. Alternatively, you can use another data structure that allows dynamic size allocation e.g std::vector.
Good luck!
I am quite an experienced python programmer, attempting to learn C++. I am having an issue with initialising an integer array of a fixed size.
I have read this but creating my integer as a constant has not fixed my issue. What am i missing here?
BTW i am using VS2019 Community, any help would greatly be appreciated!
#include <iostream>
#include <sstream>
int numericStringLength(int input) {
int length = 1;
if (input > 0) {
// we count how many times it can be divided by 10:
// (how many times we can cut off the last digit until we end up with 0)
for (length = 0; input > 0; length++) {
input = input / 10;
}
}
return length;
}
int convertNumericStringtoInt(std::string numericString) {
std::stringstream data(numericString);
int convertedData = 0;
data >> convertedData;
return convertedData;
}
int main() {
std::string numericString;
std::cout << "Enter the string: ";
std::cin >> numericString;
const int length = numericStringLength(convertNumericStringtoInt(numericString));
std::cout << "Length of Numeric string: " << length << "\n";
int storage[length];
}
but creating my integer as a constant has not fixed my issue
It is not sufficient for the array length to be const. It must be compile time constant. const merely means that the object does not change throughout its lifetime - i.e. it implies runtime constness. Since length is not a compile time constant, the program is ill-formed. Examples of values that are compile time constant:
Literals such as 42
Template arguments
Enumerations
constexpr variables
const variables with compile time constant initialiser (this may have some limitations, I'm not sure)
It should be quite clear from the program that the length is calculated from user input, which would be impossible to do when the program is compiled. So since you cannot make it a compile time constant, you cannot use an array variable. You need to allocate the array dynamically. Simplest solution is to use a vector:
std::vector<int> storage(length);
Making the variable const is not enough.
const just means "I won't change this after it's initialised".
It has to be a compile-time constant, as the machinery for a basic C array is baked into the computer instructions that form your executable.
You're calculating it at runtime, so there's no way that is going to work.
You are going to have to use a vector or some other such dynamically-resizable array type.
If you want a fixed size array, you can use std::array, example:
std::array<int, 3> arr { 1,2,3 };
// ^
// fixed size needs to be known at compile time
If you don't know the size at compile time, use std::vector
The problem you have is that length is a run-time constant, whose value is calculated when the program is running. This is opposed to a compile-time constant, whose value is known by the compiler when you build your program.
Arrays needs compile-time constants for their size.
If the size is not known at compile-time but only at run-time, then you should use std::vector.
I'm a novice programmer trying to get a head start on some classes before the summer semester starts, and I've run into this problem while trying to create a Quick Union algorithm in C++.
I've been trying to figure out why my program creates two identical arrays, despite having two separate for loops designed to create two different arrays. Whenever my program runs to completion and prints id[] and sz[], it always outputs 1 as the element at every index in both arrays.
class quickUnionUF{
private:
int id[];
int sz[];
int root(int);
public:
quickUnionUF(int, int);
bool connected(int, int);
void unionPoint(int, int);
void print();
};
quickUnionUF::quickUnionUF(int n, int b){
id[n];
sz[b];
for(int i=0;i<n;i++){
id[i] = i;
}
for(int j=0;j<b;j++){
sz[j] = 1;
}
}
For example, if I create quickUnionUF(5, 5);
id[] should now contains elements:
0, 1, 2, 3, 4
And sz[] contains elements:
1, 1, 1, 1, 1
However, the program creates an array sz[] AND array id[] with elements:
1, 1, 1, 1, 1
Any thoughts as to why this is happening?
Standard C++ does not have sizeless array members.
Use std::vector<int> as dynamically sized arrays in C++.
#include <vector>
class quickUnionUF{
private:
std::vector<int> id;
std::vector<int> sz;
int root(int);
public:
quickUnionUF(int, int);
bool connected(int, int);
void unionPoint(int, int);
void print();
};
quickUnionUF::quickUnionUF(int n, int b)
: id(n)
, sz(b)
{
for(int i=0;i<n;i++){
id[i] = i;
}
for(int j=0;j<b;j++){
sz[j] = 1;
}
}
Your code hints at a two very important mistakes:
C++ does not work like Java. int id[] is not an reference to an array of arbitrary size on the garbage collected heap. It is instead a member array of undefined size used to implement dynamic arrays (and similar features) in C99. You should never use this syntax unless you know exactly what you are doing, because it is almost guaranteed to be wrong otherwise.
id[n] does not allocate an array at all. Instead it just indexes id and discards the result.
Listen to your compiler!
First, your code should not compile due to the fact, that only the last member of a struct may be a flexible array type. In fact clang howls:
main.cpp:53:9: error: field has incomplete type 'int []'
int id[];
MSVC howls:
1>main.cpp(54): error C2229: class 'quickUnionUF' has an illegal zero-sized array
And g++ only warns (well, g++ is strange in what it accepts sometimes):
main.cpp:53:12: warning: ISO C++ forbids zero-size array ‘id’ [-Werror=pedantic]
int id[];
Note: g++ is wrong in compiling this, even if one allows flexible array members. This is defined in C99 6.7.2.1§16 and C11 6.7.2.1§18 both of which begin with (emphasis is mine):
As a special case, the last element of a structure with more than one named member may
have an incomplete array type; this is called a flexible array member. [...]
What is happening?
Well, assuming you got your code to compile anyway, it basically means the following:
Create an object with the alignment of integers, but NO elements at all. Take a peek at the following test program:
quickUnionUF q;
::std::cout << sizeof(quickUnionUF) << "\n";
::std::cout << &q << "\n" << &q.id[0] << "\n" << &q.sz[0] << "\n";
The only compiler that managed to compile this at all (gcc 4.9.0) gave the following result:
0
0x7fff1bf6274c
0x7fff1bf6274c
0x7fff1bf6274c
So, this is a zero byte object (yes, this is illegal C++, since every C++ object has a size > 0) and the first element of each array is at the same position (OUTSIDE YOUR OBJECT!). Remember, you declared id and sz to have zero elements!
Therefore, you are writing to the same arbitrary position. You can consider this the extreme case of a buffer overflow: By writing 5 integers to a zero size buffer, you are overflowing from the first zero size buffer through the second zero size buffer into memory totally not under your control.
This also explains your observed result: The second loop simply overwrites what the first did (and it still does it by corrupting your stack).
How do I fix this?
Just use a vector. You can tell it how big you want it and you can ask it to tell you when you are indexing to some position that is not yours.
const int sizea = 600;
char sz[sizea];
above code works fine. But below code segment cause errors.
I'm working on visual studio 2005 - MFC application
CString strFinal;
.......//strFinal value is dynamically changing . .
const int size = strFinal.GetLength();
char sz[size];
Error 2 error C2057: expected constant expression
Error 5 error C2070: 'char []': illegal sizeof operand
Error 4 error C2133: 'sz' : unknown size Error 3 error C2466: cannot allocate an array of
constant size 0
In the current version of C++, arrays must have a fixed size, specified by a compile-time constant. If you need to use a run-time value, then your options are:
most portably, use a dynamic array class such as std::string or std::vector<char>;
use a compiler that supports C99 variable-length arrays as a non-standard extension;
wait a year for dynamic arrays to (hopefully) be introduced in C++14 (and perhaps wait a bit longer for your compiler vendor to catch up).
Normal use-case is to use new (and delete when you're done) for variable-sized elements. If you must use the stack, you can use alloca.
char *psz = new char[size+1]; // +1 you probably want zero-termination
...
delete [] psz;
you can use vector as a dynamic array. Try this.
#include <vector> // use this header
#include <iostream>
using namespace std; // use this namespace
int main()
{
vector<int> v; //declare dynamic array equivalent
for (int i = 0; i < 10; ++i) {
v.push_back(10 + i);
}
cout << "vector data: " << endl;
print_collection(v);
while (v.begin() != v.end()) {
cout << "v.back(): "; print_elem(v.back()); cout << endl;
v.pop_back();
}
}
It produces an error because GetLength() returns you an arbitrary value, not statically defined.
The proper way is to allocate enough memory to hold your string and, if required, the NULL-terminated symbol either by calling malloc or by using the new operator (if compiling with C++ compiler).
I did something like this long time ago
the Idea is to work with pointers.
so you need to make structure that has (char and nextPointer)
the char represent the current value of the array and the nextPointer represent the next structure of the series
looping all through that pointers u will have your array of whatever you want your structure connected
struct yourStructure {
Char char;
double nextPointer;
} ;
so you create first structure and connect to the second and the tree
#ifndef QWERT_H
#define QWERT_H
const int x [] = {1, 2,};
const int z = 3;
#endif
#include <iostream>
#include "qwert.h"
class Class
{
int y [x[0]]; //error:array bound is not an integer constant
int g [z]; //no problem
};
int main ()
{
int y [x[0]]; //no problem
Class a_class;
}
I can't figure out why this doesn't work. Other people with this problem seem to be trying to dynamically allocate arrays. Any help is much appreciated.
x is const (as is z obviously), but x[0] is not a constant expression. Array declarations in a class definition must have constant size specifiers.
Consider this for a moment; how would you expect the sizeof operator to evaluate the size of your class if it contains an array of unknown size at compile time?
The main version works because your compiler has an extension to allow for variable length arrays. Array accesses cannot be constant expressions in C++03, even if the array and the index are both constant expressions, which is the source of the error.
The size of an array must be a constant expression. I don't believe that constant elements in an array qualify as such.
The version in main() working is probably due to a compiler extension.