class matrix
{
public:
int m;
int n;
int mat[m][n];
};
I get this error:
[Error]: Invalid use of non static data member 'matrix::n'
On declaring static:
class matrix
{
public:
static int m;
static int n;
int mat[m][n]; //Error
};
I get this error:
[Error]: Array bound is not an integer constant before ']' token
Please tell me what these errors mean and how to fix this problem.
The sizes of arrays in C++ must be compile-time evaluable.
The compiler doesn't know what to do with int mat[m][n]; since the values of m and n are not known at compile time.
If you want a good reliable matrix class then consider using the BLAS library in Boost. A std::vector<std::vector<int>> can work but it is a jagged-edged matrix with a rather poor memory model.
The problem is that when you declare mat the member variables m and n doesn't actually exist. They don't exist until you create a an instance of the matrix class. However that won't do much good as arrays in C++ must have a fixed size at the time of compilation.
If you want to set the size of mat at run-time, then the simple solution here is to use a std::vector of std::vector objects.
Like e.g.
std::vector<std::vector<int>> mat;
Related
#include < vector >
using namespace std;
class Rclass
{
public:
vector<int> ir0T;
vector<int> ir1T;
private:
int f();
}
int Rclass::f()
{
ir0T.clear();
ir1T.clear();
ir0T.push_back(1);
ir1T.push_back(2);
}
this throws error
"Rclass.cpp:90: error: member function 'clear' not viable: 'this' argument has type 'const vector', but function is not marked const
ir0T.clear();
^~~~"
Rclass.cpp:91: error: member function 'clear' not viable: 'this' argument has type 'const vector', but function is not marked const
ir1T.clear();"
why?
^~~~
I tried adding "const vector ir0T;"
You cannot set the matrix member variable to a local varable created in a local member function - the local variable will be destroyed when the function ends and then the matrix member variable won't be pointing to anything. So instead, if you insist on using a raw pointer, use calloc() because it allocates the memory like malloc and then it sets it all to zero. The main problem with this is that then you need a copy constructor, assignment operator and destructor - That's not the way to go if you can help it. It would be better to use a std::vector<std::vector<int>> because all the dynamic allocation and deallocation is hidden from you. Plus you can reserve the size if you know it ahead of time. How to initializ the "vector"-ized version to zero can be seen here: Initializing a two dimensional std::vector
#include <vector>
class CS
{
private:
std::vector<std::vector<int> > Rightalpha;
public:
void CreateMtrx(int a, int b)
{
// Defaults to zero initial value
Rightalpha = std::vector<std::vector<int> >(a, std::vector<int>(b));
}
};
int main()
{
CS cs;
cs.CreateMtrx(4,4);
return 0;
};
A better alternative if it is fixed and you know ahead of time how big the matrix is: you can just use a plain array directly as a member variable instead of using a pointers to dynamically allocated memory. If the matrix is small (like 4x4) this will give you cache locality and a performance improvement. Plus if you are using c++11 you can clear the array at the declaration and you don't need a CreateMatrix() member variable at all - something like this:
class CS
{
private:
int Rightalpha[4][4] = {};
};
int main()
{
CS cs;
return 0;
};
Or like one of the comments suggested you could use std::array instead of a plain array, if you want a nice STL-like interface to the array. There are some advantages listed here: Replace fixed size arrays with std::array?
Firstly a few fundamentals.
When CreateMtrx() returns Rightalpha will become invalid as a will destruct.
And I would recommend using lower camel case naming for variables and upper camel case for types. i.e. rightAlpha instead of Rightalpha, to avoid confusion with types.
As for your actual question you can initialise a 2D array with a nested loop:
for(unsigned int i = 0; i < 4; i++)
{
for(unsigned int j = 0; j < 4; j++)
{
rightAlpha[i][j] = 0;
}
}
Finally, when asking for help 'craps up' is not conducive to constructive answers. It is important to be clear on what your expected behaviour is and what results you are actually seeing.
If Rightalpha is a data member of your class it doesn't need to be an int**. You probably just want it to be an int[4][4] and skip using a local variable 'a' in your create function.
If you really want it to be a pointer, just make it an int*, and use it with 2D-array syntax. Instead of: int a[4][4]; Do: int* a = new [4*4];
I see from the comment that you can't change the type of Rightalpha. You will then need to do manual memory management. You will need to initialize you int** with the new operator.
You will need to allocate each array in the 2D array.
rightAlpha = new int*[4];
for (int i = 0 ; i < 4 ; i++) {
rightAlpha[i] = new int[4];
}
You can read more about initialisation of a multi-dimentional arrays here:
How do I declare a 2d array in C++ using new?
Even if that works, you will need to free and manage memory and deal carefully with all the pitfalls of manual memory management. That's why I strongly suggest to use a std::vector<int>:
struct CS {
createMatrix() {
rightAlpha = std::vector<int>(4*4);
}
private:
std::vector<int> rightAlpha;
With this solution, you don't need to worry about memory stuff as the std::vector will do it for you.
If you need matrix semantics, you can add a function that returns the right element according to a j i position.
int operator()(int i, int j) const {
return rightAlpha[j+4*i];
}
It may be used like this:
CS myCs;
myCs(3, 2);
I am making a polynomial program, and below is the code I have written for it.
class Polynomial{
private:
int n; //n = degree of polynomial
double a[n]; //a = array of coefficients where a[i] is the coefficient of x^i
double roots[n];
double maxima[n-1],minima[n-1],inflection[n-1]; //arrays of coordinates of maxima, minima and points of inflection
This is just a part of the class Polynomial in the header file. When I try compiling, it gives me the following error
invalid use of non-static data member int n;
and when I make n static , it gives me the following error
array bound is not an integer constant before ‘]’ token
This is on compiling the header file alone. What am I doing wrong?
Your class contains VLA (variable lenghth arrays) which is not
supported in C++.
You need to either determine the size by making n constant
or use another type of container that is dynamic, std::vector
is a container that resembles an array but is dynamic i.e. can
be expanded during runtime.
class Polynomial
{
static const int n = 10;
double a[n];
...
class Polynomial
{
std::vector<double> a;
The size of C-style arrays must be known at compile time.
If n is in fact known at compile-time, you could make it a template parameter instead of a member variable.
If not then you will have to use a different container, such as vector<double> a, roots, maxima, minima, inflection; .
You can simply allocate all these in a constructor using new.
Or use vectors.
class Polynomial
{
vector<double> a;
Polynomial()
{
a.assign(n,0);
...
}
..
};
Without getting into complications,
the simple answer is that for static memory allocation to work (which is what you are trying to do with double a[n];) you need to know the size of the array at compile time.
However, if you do not know the size of the array even before the program runs, but instead, expect to know it somewhere during the runtime of the program, then you need to use dynamic memory allocation.
To do this you will have to
Declare pointers instead of static arrays.
and
Assign them memory using the new directive
and then later
When you don't need them, for instance when the scope of the class ends, you will have to free the memory you allocated using the delete directive with [] parenthesis to indicate the compiler to free memory for more than one consecutive variable.
Do something like:
class Polynomial{
private:
int n; //n = degree of polynomial
double *a; //a = array of coefficients where a[i] is the coefficient of x^i
double *roots;
double *maxima,*minima,*inflection; //arrays of coordinates of maxima, minima and points of inflection
public:
Polynomial( int degree_of_polynomial ){
n = degree_of_polynomial;
a = new double[n];
roots = new double[n];
maxima = new double[n-1];
minima = new double[n-1];
inflection = new double[n-1];
~Polynomial(){
delete []a;
delete []roots;
delete []maxima;
delete []minima;
delete []inflection;
}
}
For a more detailed explanation of dynamic memory allocation see this link.
I have a structure defined in a file called 'xxx.h':
struct struct_name
{
declarations;
};
I included this header - 'xxx.h' - in another c++ file, yyy.cpp
And then I try to create a 2D array of the above structure using new keyword as follows (I learnt how to create a 2D array of structures from this link: Declaring a 2D array of type struct in c++).
struct struct_name * some_name;
some_name = new struct struct_name[x][y];
When I compile, I get the following error: error: ‘y’ cannot appear in a constant-expression. This error particularly points to the second dimension of the array.
Also When I tried to initialize this 2D array of structures with some value like:
some_name[i][j].var_name = value;
I get the following error:
error: no match for ‘operator[]’ in ‘*(some_name + ((sizetype)(((unsigned int)i) * 12u)))[j]’
Please advise me how to fix this.
Thanks.
In the interest of getting you up and running as quickly as possible, I'm going to belay the usual memory layout diatribe and simply tell you one way to get your situation resolved.
The reason you're error is happening is because C++ requires knowledge of types when declaring an array, allocating an array, etc. When you do this:
some_name = new struct_name[x][y];
what you're telling the compiler is "I want to allocate x objects of type struct_name[y]". But struct_name[y] isn't a type known at compile-time. The size is unknown, but must be known (thus the error about a constexpr expectations. This would work:
struct_name (*some_name)[WIDTH] = new struct_name[x][WIDTH];
would work if WIDTH is a compile-time known-constant. But for you, that isn't constant so another solution is required.
Altnerative Approach
An alternative quick-fix approach is presented below
#include <vector>
int main()
{
int rows, cols;
// get row and column count.
typedef std::vector<struct_name> MatrixRow;
typedef std::vector<MatrixRow> Matrix;
Matrix some_name(rows, MatrixRow(cols));
// use some_name[i][j] however you need
return 0;
}
There are other ways to do this, but this is likely the fastest way to get you running. Further, it promotes proper RAII concepts. If you need a more specialized purpose of a 2D matrix you may have to develop your own class, as the C++ standard library has no direct 2D dynamic array concept natively, thus why we invent it using a vector of vector-types.
Try the declaration within yyy.cpp as:
struct struct_name **some_name;
The reason for this is that some_name[i] needs to be of type struct_name * in order to access another level of variables.
Do you really need a c++ arrays?
Why not use std::vector<std::vector<struct_name>> ?
If you don't need dynamic allocation then you could use:
std::array<std::array<struct_name, 2>, 3> where 2 and 3 are the sizes of your 2D array.
I've got a class and I'm going to declare the size of the array (two dimensional) based on input from a user.
so :
class myClass {/*...*/}
int main(){
myClass* arrayObj = new myClass[100][100];
That works fine, and it should put the array on the heap.
But I need to do :
int arraySize;
cin >> arraySize;
myClass* arrayObj = new myClass[arraySize][arraySize];
I am getting the error :
"arraySize" cannot appear in a constant-expression.
I'm assuming that means that I can only have constants in the declaration of the array, but if not, then how can I do it?
The array is too big to fit on the stack, that is why I am doing it on the heap in the first place.
Edit : I've got it working with the pointers, but I'm having another problem, I have a function that is using the array, ie.
void myFunction()
{
/*...*/
arrayObj[something][something].variable = somethingElse // error here
}
int main ()
{
/*...*/
int arraySize;
cin >> arraySize;
MyClass **arrayObj = new MyClass*[arraySize]
for (int i = 0; i < arraySize; i++) arrayObj[i] = new MyClass[arraySize]
/*...*/
}
I'm getting : error: 'arrayObj' was not declared in this scope.
I can see why, but it's on the heap and it's a pointer, shouldn't it be global? If not, how would I make it global?
First of all you are mistaken saying that this
class myClass {/*...*/}
int main(){
myClass* arrayObj = new myClass[100][100];
works fine. The compiler shall issue an error because there is no implicit conversion from myClass ( * )[100] to myClass *
As for your problem then you should use the following approach:
myClass **arrayObj = new myClass *[arraySize];
for ( int = 0; i < arraySize; i++ ) arrayObj[i] = new myClass[arraySize];
C++ doesn't really have a built-in model of variable sized multi-dimensional arrays. Only the outermost dimension can vary at run-time, all other dimensions are fixed. The background is how C++ does address arithmetic: when adding an offset to a pointer it is advanced by the size of an object with a statically determined size.
If you want to have a multi-dimensional array varying in other dimensions, you'll need to use a suitable class or implement one yourself (the standard C++ library has std::valarray<T> to sort of deal with multi-dimensional arrays but their use is, let say, not entirely straight forward). The easiest approach is probably to use a std::vector<std::vector<myClass> >.
A more efficient approach is to allocate a large std::vector<myClass> as a member of a class and have operator[]() for this class return a view to a corresponding section of this array. For starters I would probably just use a std::vector<std::vector<myClass> > wrapped into a class and change the implementation if it turns out to be too inefficient.
If you must use arrays, then another way to get around this is impose a limit on the number of elements in the array and make sure that this limit is enforced in your code. This is one of the disadvantages of using arrays vs. std::vectors. Arrays are a fixed size while vectors can keep growing dynamically. By the way, what do you mean by "The array is too big to fit on the stack, that is why I am doing it on the heap in the first place."? If it is too big to fit on the stack, then maybe we should look at why the array is so large in the first place. Maybe there is a better way to solve whatever problem you're trying to deal with.
The sample code below shows what I am trying to do:
template<int NX, int NY>
class Array
{
public:
float v[NX][NY];
};
void main()
{
Array<10,20> grid;
}
The above code won't compile, but it shows what I want to do. We have a class that contains an array, and the array class doesn't know its size until compile time. Is there a simple way to do this?
Edit: I want to write a simple reusable array class. That means I need to find a good way to separate the array size from the class.
I also want the class to be fast (and simple) so it must not be dynamically allocated. That means the size can't be given during run time.
I also don't want to use the preprocesser to define the size because that means I will have to go through the hassle of changing a number somewhere. That isn't convenient enough.
Basically, the class doesn't know its own size until compile time, because that is when the main function tells the class its size.
Edit: The above code is good.
Other than main not returning an int, this is legal code and should compile. In fact, on some compilers this will compile without main returning an int, such as VC++ but this is non-standard behaviour.
You can also store the size at compile time so that you don't have to calculate it manually.
#include <iostream>
template<int NX, int NY>
class Array
{
public:
float v[NX][NY];
int size() const { return ArraySize; }
private:
enum { ArraySize = NX * NY }; // You can also store rows/cols individually
};
int main()
{
Array<10,20> grid;
std::cout << grid.size();
return 0;
}
Boost.MultiArray might fit your needs.