Indexing matrix element member of struct - c++

I'm trying to index an element from a matrix, which has been declared by creating a vector of vectors inside a struct.
Here's my code:
#include <vector>
using namespace std;
const int MAX_DIM = 1000;
struct TestStruct{
int MAX_DIM;
vector<vector<int> > matrix (int MAX_DIM, vector<int>(int MAX_DIM));
};
int main(){
TestStruct ts;
ts.MAX_DIM = 100;
ts.matriz[0][0] = 1;
return 0;
}
While compiling I've recieved the following error:
test.cpp:14:17: error: invalid types ‘<unresolved overloaded function type>[int]’ for array subscript
mierda.matriz[0][0] = 1;
Btw, do you know any other "cleaner" way to declare the matrix (without using anything else than vector from the class Vector)?
Thanks in advance!

The problem in your code and your logic is that you think the line:
vector<vector<int> > matrix (int MAX_DIM, vector<int>(int MAX_DIM));
Creates a matrix inside your struct.
In fact, you just declared a function named matrix that returns a vector<vector<int>. To have a member object inside your struct, you need to delete the parentheses, as such:
vector<vector<int> > matrix;
I assume you want to first specify the MAX_DIM value and then create a matrix based on that value. I would either recommend creating a constructor that takes an int as argument to assign that value to MAX_DIM and then create a matrix based on that value, or to create an initialise() function that needs to be called before you access the matrix.
First, preferable solution:
using namespace std;
const int MAX_DIM = 1000;
struct TestStruct{
TestStruct(int MD){
MAX_DIM = MD;
matrix = vector<vector<int>>(MD, vector<int>(MD));
}
int MAX_DIM;
vector<vector<int>> matrix;
};
int main(){
TestStruct ts(100); // matrix 100 by 100
ts.matrix[0][0] = 1; // works
return 0;
}
Or, if you don't want to deal with constructors:
using namespace std;
const int MAX_DIM = 1000;
struct TestStruct{
int MAX_DIM;
vector<vector<int>> matrix;
void initialise(){
matrix = vector<vector<int>>(MAX_DIM, vector<int>(MAX_DIM));
}
};
int main(){
TestStruct ts;
ts.MAX_DIM = 100; // specify the size
ts.initialise(); // construct the matrix
ts.matrix[0][0] = 1; // works again
return 0;
}
Note that the first solution requires less code and is more readable inside the main function. If you choose the second one, it will be easy to forget to either assign value to MAX_DIM or to call initialise().

Related

How to create a Eigen VectorXd object from pointer without data copy

I have a double pointer, store some data in it.
I want directly create a VectorXd on the pointer without copy. That is, the data stored in VectorXd is just the data stored in pointer. They are shared.
I know it is easy to create a VectorXd object then copy data into it from the pointer. I do not want the element by element copy happen in order to reduce copy overhead. It is already be proved be the performance bolttleneck in my application.
#include <Eigen/Core>
using namespace Eigen;
int main()
{
double *ptr = new double [100];
// fill something into pointer ...
VectorXd vector(ptr); // dicretely construct vector from pointer without data copy
// using vector for some other calculation... like matrix vector multiple
delete[] ptr;
return 0;
}
I apologize if it is a stupid problem. Thanks for your time.
You need to use a Map object:
#include <iostream>
#include <Eigen/Core>
using namespace std;
using namespace Eigen;
int main()
{
const int N = 100;
double *ptr = new double[N];
for (int i = 0; i < N; i++)
{
ptr[i] = double(i);
}
Map<VectorXd> vector(ptr, N);
vector *= 2;
cout << ptr[32] << endl;
// 64
delete[] ptr;
return 0;
}

How to declare new private variables from constructor?

I want to pass 2-dimensional arrays with different sizes to my class and store the arrays as private member variables.
When I try to declare the array in the constructor I get an error.
How should I declare a private variable from constructor?
If it is not possible, what else can I do to make my class flexible for different array sizes?
Here is the header file:
#ifndef NUMCPP_H
#define NUMCPP_H
class numcpp
{
public:
numcpp(int *Arr,int *Shape,int Dims);
private:
int *shape;
int dims;
};
#endif
Here is the source file:
#include <iostream>
#include "numcpp.h"
using namespace std;
numcpp::numcpp(int *Arr,int *Shape,int Dims) // *arr points to input array's first element
{
shape = Shape;
dims = Dims;
int i = shape[0];
int j = shape[1];
int numcpp::array[i][j]; // error happens in this line
//assigning input array to our variable
for (int x = 0; x < i; x++)
{
for (int y = 0; y < j; y++)
{
array[x][y] = *(arr + (x * i) + y);
};
};
};
Classes must have a compile time fixed size, so a true flexible array member isn't possible. The best you could do is either:
Templating the class on the array dimensions (compile time chosen fixed size)
Using a dynamically resizable type like std::vector<std::vector<int>> to get something functionally similar (runtime dynamically chosen size); the class itself remains fixed size, with the vector storing the dynamically allocated arrays on the free store (heap).
One implementation approach would look something like this (adding a declaration of std::vector<std::vector<int>> array; in the private section of the class declaration):
// Use initializers to initialize directly instead of default initializing, then replacing
numcpp::numcpp(int *arr,int *Shape,int Dims) : shape(Shape), dims(Dims), array(shape[0], std::vector<int>(shape[1]))
{
int i = shape[0];
int j = shape[1];
for (int c = 0; c < i * j; ++c) {
array[c / j][c % j] = arr[c];
}
};

Organising C++ code

I am looking for some advice on how to organise my C++ code.
I have an int array, side, that I would like to be static in the sense that its value is kept constant between calls. This is because my function foo(), will modify the array side recursively and so I don't want copies to be made of side. Furthermore, the size of side can only be determined at compile time from the size of a vector that is passed into the function bar().
I have thought of the following structure to layout such a problem.
I keep a global int pointer, side, which I can then use to point to the address of my int array and then use the pointer *side within foo to do my modifications.
Please can you give me advise on the layout and organisation of this code? I am quite new to C++ so would appreciate any advice on the below structure.
#include <iostream>
#include <vector>
using namespace std;
int *side;
class A {
public:
int foo(bool);
int bar(vector<int>);
void set_n(int n){ class_n = n;};
private:
int class_n;
};
int A::foo(bool fl)
{
int n = class_n;
for(int i = 0; i < n; i++) {
// modify side[] and then recursively call foo
}
return 0;
}
int A::bar(vector<int> t)
{
int size = t.size();
set_n(size);
int a = foo(true);
int *side_local = new int[size];
for(int i = 0; i < size; i++) {
side_local[i] = 0;
}
side = side_local;
return 0;
}
int main()
{
A a;
vector<int> t = {1, 2, 3};
a.bar(t);
return 0;
}
A recursive call can pass a pointer to itself:
void foo(int *pList)
{
foo(pList); // recursive
}
the same list is then being worked on.
That being said, since foo is inside a class you wouldn't need a global either, but a member variable.
class A
{
int *pMemberList;
...
void foo();
}
now foo can see pMemberList all the time.
BUT ... passing it is probably a better option as in the future your class might house 2 lists that you want to do foo on.

Convert Struct type to vect int

I have problem i need to convert from my "Array" structure to std::vector<int>... the point is i have a dynamic matrix who purpose is being Database. But at some point i need to move some values from the 'Array' to a vector. and i get the fallowing error
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits /stl_iterator_base_types.h:166:53: error: 'int' is not a class, struct, or union type
Anyone has some clue how to achive this thing?
structure:
const int days=31;
const int exp=6;
struct Arr{
int days;
int exp;
int **M;
};
typedef Arr* Array;
vector:
vector <int> vec(31);
EDIT:
int dayExp(int day, Array &M){
int s=0;
for(int i=0;i<6;i++){
s += M->M[day][i];
}
return s;
}
void srtDesc(Array &M){
vector <int> vec(31);
for(int i=0;i<31;i++){
vec[i]=dayExp(i, M);
}
sort(vec[0],vec[1]);
for(int i=0;i<31;i++){
cout<< vec[i];
}
}
Your Arr struct does not implicitly convert to int. First of all, your struct contains 3 int types, whereas a vector<int> is one int at a time.
If you want to put your Arr into a vector, you should create a std::vector<Arr> and then call push_back on it to put your Arr structs in it.
std::vector<Arr> myvec;
myvec.push_back(someArr);
You will need to create for loop that goes through the length - 1 of your array and calls push_back to put each item in the vector

beginner question about arrays in structs in C++

I would like to create a struct and use it inside an other struct as an array. My problem is that I don't know how big array I would like to allocate, I will only know once I am in a function. I mean I would like to use [] instead of a pre-determined constant, like 10000.
I think if you look at my code it would be self-explanatory. Can you help me how to make this code work? Moreover it would help me a lot if you could tell me what is the name of the topic I am asking about (is it dynamic arrays?) and that where can I find articles/tutorials about this topic.
Here is the code with my broken way of thinking about arrays in structs.
#include <iostream>
using namespace std;
struct keyframe {
bool a;
int b;
int c;
};
struct keyframe_file {
const int num_views;
const int num_keyframes;
keyframe keyframes[];
};
int main() {
keyframe_file my_file;
my_file.num_views = 1;
my_file.num_keyframes = 6;
my_file.keyframes = new keyframe[my_file.num_keyframes];
my_file.keyframes[0].a = true;
my_file.keyframes[0].b = 5;
my_file.keyframes[0].c = 9;
return 0;
}
Use a std::vector.
struct keyframe_file {
const int num_views;
const int num_keyframes;
std::vector<keyframe> keyframes;
};
int main() {
keyframe_file frame;
frame.keyframes.resize(...);
}
If it suits your purpose, an STL container (std::vector) is easily one of the best options - the less memory management you have to worry about, the better.
In any case, look at the struct definition Nawaz posted above - that's exactly how it should be. Dynamic arrays in C++ are simply pointers. You have, however, allocated the memory properly in your code, but you haven't freed it (so it's leaking). Since you allocated with new [] you will need to
delete [] my_file.keyframes;
in order to free the memory properly.
Resizing is another issue: with a smart implementation, array resizing can be an amortized O(1) operation which is nice. When you resize, it will always take you O(n) since you need to copy all the elements into a new array of different size, but if you do it half as much, it becomes O(1). That is, double the array each time you need to resize. Here is a very quick example
void resize()
{
if(numOfElementsInArray == sizeOfArray)
{
ArrayType * arr = new ArrayType[sizeOfArray*2]; // Allocate a double size array
for(int i=0;i<sizeOfArray;++i)
currentArray[i] = arr[i];
delete [] currentArray; // Free memory in old array
currentArray = arr; // Set the array to our new one
sizeOfArray *= 2; // Double the size
}
}
NOTE: The example above does not take into account space complexity; that said, if you have 5000 elements, and remove all but 5, this method with not shrink it (which is probably what you will want to do for all practical purposes)
Your code appears to be almost correct, except for two things:
keyframes needs to be a keyframe* rather than a keyframe[]
You forgot to delete the memory you allocated
That is incomplete type. In C++, array must be provided with size, and the size must be known at compile time itself.
You're using new, with which you should be using pointer.
struct keyframe_file {
const int num_views;
const int num_keyframes;
keyframe *keyframes;
};
But std::vector<keyframe> is still a better choice, as #DeadMG already suggested.
By the way, the first two members are const in the struct, that means, they cannot be assigned value, as you're doing in your code. They must be initialized with values you want them to hold. That implies, now with vector, you've to include a constructor, to initialize the struct, as the struct is no more a POD.
struct keyframe_file {
const int num_views; //const member
const int num_keyframes; //const member
std::vector<keyframe> keyframes;
keyframe_file(int nviews, int nkeyframes)
: num_views(nviews), num_keyframes(nkeyframes), keyframes(nkeyframes){}
};
keyframe_file my_file(1,6); //done!
The suggested "Vector" is they safest way to do it.
But if it is only about making your code work (without resizing and stuff) the following should be working:
#include <iostream>
using namespace std;
struct keyframe {
bool a;
int b;
int c;
};
struct keyframe_file {
const int num_views;
const int num_keyframes;
keyframe* keyframes;
};
int main()
{
keyframe_file my_file = {1, 6}; // initialization needed bcause of 'const int'
my_file.keyframes = new keyframe[my_file.num_keyframes];
for (int i = 0; i < my_file.num_keyframes; i++)
{
my_file.keyframes[i].a = true;
my_file.keyframes[i].b = 5 + i;
my_file.keyframes[i].c = 9 - i;
}
return 0;
}
somewhere in your code, when you are done using the array you have to call delete [] my_file.keyframes; as already mentioned.
There's a basic rule when using dynamic arrays in c++, especially when using it inside structs or classes, and it's to delete what you no longer need.
If you want to make your struct dynamic, it's easy, just replace the [] with * and the array will become dynamic, but it's not over yet, there is a lot of work.
You have to construct the array and destory it, and destoroying it is possible and useful noly with destructors, like this:
struct keyframe_file
{
const int num_views;
const int num_keyframes;
keyframe* keyframes;
~keyframe_file() // this is the destructor
{
delete[] keyframes;
}
};
Yet even that code isn't going to work at all, since you are assigning values to constants in variable my_file after creating it, it's illegal in c++, you should then use classes instead.
Using classes with dynamic arrays is very easy and interesting and makes your code very good, you don't have to know too much to do that, just learn what is a constructor, an initializer, destructor, private and public and go on with the following code:
#include <iostream>
using namespace std;
struct keyframe
{
bool a;
int b,c;
};
class keyframe_file
{
public:
keyframe_file(int NV, int NKF):num_keyframes(NKF),num_views(NV)
{
keyframes = new keyframe[num_keyframes];
}
~keyframe_file()
{
delete[] keyframes;
}
private:
const int num_views;
const int num_keyframes;
keyframe* keyframes;
};
int main()
{
keyframe_file my_file(1,6);
return 0;
}
This code works very well, it allows you to assign value to the constants num_views and num_keyframes for one time when creating the object (variable) my_file.
Remember, you are a C++ programmer, be proud of that, and use classes instead of structs and dynamic arrays instead of static ones.
Hope that's useful.
Use pointers and apply to your structure!
int *p;
p = new int;
#include <iostream>
using namespace std;
struct keyframe {
bool a;
int b;
int c;
};
struct keyframe_file {
const int num_views;
const int num_keyframes;
keyframe *keyframes;
};
int main() {
keyframe_file my_file;
my_file.num_views = 1;
my_file.num_keyframes = 6;
for (int i = 0; i < my_file.num_keyframes; i++){
my_file.keyframes = new keyframe; //<---
}
my_file.keyframes[0].a = true;
my_file.keyframes[0].b = 5;
my_file.keyframes[0].c = 9;
return 0;
}