Passing an array in struct initialization - c++

I would like to create a struct which contains both an int and an array of int. So I define it like
struct my_struct {
int N ;
int arr[30] ;
int arr[30][30] ;
}
Then I would like to initialize it with an array which I have already defined and initialized, for example
int my_arr[30] ;
for (int i = 0; i < 30; ++i)
{
my_arr[i] = i ;
}
Then I thought I could initialize a struct as
my_struct A = {30,my_arr}
but it doesn't seem to work (gives conversion error).
P.s. and how would it work with a 2d array?

Arrays cannot be copy-initialised. This isn't particular to the array being member of a class; same can be reproduced like this:
int a[30] = {};
int b[30] = a; // ill-formed
You can initialise array elements like this:
my_struct A = {30, {my_arr[0], my_arr[1], my_arr[2], //...
But that's not always very convenient. Alternatively, you can assign the array values using a loop like you did initially. You don't have to write the loop either, there's a standard algorithm for this called std::copy.

Related

Variable-sized object may not be initialized problem in array

When I try to run this simple code, it returns a Variable-sized object may not be initialized error. I have no idea why and how to resolve this problem.
int main()
{
int n=0;
n=1;
int a[n]={}, b[n]={};
return 0;
}
The array lenght must be known at compile time.
Either
int a[1];
or
constexpr int n = 1;
int a[n];
Otherwise you need a dynamic array like the std container std::vector.
You can initialize your array properly with the std::fill_n like:
std::fill_n(a, n, 0);
std::fill_n(b, n, 0);
or use std::vector like:
std::vector<int> a(n);
It will initialize all the elements to 0 by default.
Or, you can have something like:
constexpr size_t n = 10;
int a[n]{};
This will also initialize all the elements to 0.
Try this:
const int n=1;
int main()
{
int a[n]={}, b[n]={};
return 0;
}
The above code will let you create an array with length n.
Note: n can't be changed.

How do I set a whole struct to null?

struct zaidejas {
int numeris;
int aiksteleje;
bool penketas;
};
int main(){
zaidejas z[12];
z = {};
}
I get an error in the line of z = {}:
error: assigning to an array from an initializer list
I have no idea how to fix the error. I would really appreciate any help.
You can't assign to an array, only initialize it when you define it, or copy to it once it have been defined.
I recommend initialization:
zaidejas z[12] = {};
In C++11, you can initialize the array as follows:
zaidejas z[12]{};
If you want to initialize a single element of your array, you can use:
z[0] = zaidejas{};
This is the aggregate equivalent of the (constructor-based) initialization that was available in earlier versions of C++
z[0] = zaidejas();
You should just write
zaidejas z[12] = {};
// ^^^^
This will value-initialize all the array elements, which in turn will zero-initialize each element's class data members.
How do I set a whole struct to null?
Like this:
zaidejas z = {};
For your array, you should do:
zaidejas z[12] = {};
You have 12 elements. If you want to set all of them to null, do something like this
int main(){
int number_elements = 12;
zaidejas z[number_elements ];
for (int i = 0; i < number_elements ; z++) z[i] = {}
}

Elements of a struct when I declare it with a value

If I make a struct and in one of the elements of that struct I assign a value, whenever I declare that structure, will the element have the value instead of garbage?
For example:
typedef struct {
int var1 = 10;
int var2;
} coordinates_t;
Every time I create a variable of the type coordinates_t the element var1 of that variable will be 10?
If not, is there a way to do that or will I have to 0 every struct I create?
A code version of that question:
typedef struct {
int v1 = 10;
int v2;
} numbers_t;
numbers_t player1;
printf("%d", player1.v1);
//What will be the output?
By "valor" I assume you mean "value".
I also assume C++11, since that syntax is not allowed with C++03.
Yes, you're default initializing the int v1 with the value 10 every time you construct the struct.
_"Everytime I create a variable of the type coordinates_t the element var1 of that variable will be 10?"_
For c++ yes.
typedef struct {
int v1 = 10;
int v2;
} numbers_t;
int main() {
numbers_t player1;
printf("%d", player1.v1);
}
Output
10
Proof
For c the code fails to compile.

How to solve the error "expression must be a modifiable lvalue" in c++?

const int ADJ_MATRIX[VERTEX_NUM][VERTEX_NUM]={
{0,1,1,0,0,0,0,0},
{1,0,0,1,1,0,0,0},
{1,0,0,0,0,1,1,0},
{0,1,0,0,0,0,0,1},
{0,1,0,0,0,0,0,1},
{0,0,1,0,0,0,1,0},
{0,0,1,0,0,1,0,0},
{0,0,0,1,1,0,0,0}
};
typedef struct {
int vertex;
int matrix[VERTEX_NUM][VERTEX_NUM];
int vNum;
int eNum;
}Graph;
void buildGraph(Graph *graph){
graph->vNum = VERTEX_NUM;
graph->eNum = EDGE_NUM;
graph->matrix = ADJ_MATRIX;
}
The error occurs in this sentence:
graph->matrix = ADJ_MATRIX;
I am new to c++. please tell me why this problem occur and how to solve it?
I want to assign ADJ_MATRIX to the matrix in struct.
As was said, you can't assign arrays in C++. This is due to the compiler being a meanie, because the compiler can. It just won't let you do it...
... unless you trick it ;)
template <typename T, int N>
struct square_matrix {
T data[N][N];
};
square_matrix<int, 10> a;
square_matrix<int, 10> b;
a = b; // fine, and actually assigns the .data arrays
a.data = b.data; // not allowed, compiler won't let you assign arrays
The catch? Now the code needs some little things:
const square_matrix<int, VERTEX_NUM> ADJ_MATRIX={{
// blah blah
}}; // extra set of braces
typedef struct {
int vertex;
square_matrix<int, VERTEX_NUM> matrix;
int vNum;
int eNum;
}Graph;
void buildGraph(Graph *graph){
graph->vNum = VERTEX_NUM;
graph->eNum = EDGE_NUM;
graph->matrix = ADJ_MATRIX; // no change
}
And to access the cells, now we need to use graph->matrix.data[1][2]. This can be mitigated by overloading operator[] or operator() for square_matrix. However, this is now getting terribly close to the new std::array class, or the Boost equivalent boost::array, so it might be wise to consider those instead.
Unfortunately (or maybe fortunately, who knows...) you can't just assign one array to another in C++.
If you want to copy an array, you will need to either copy each of it's elements into a new array one by one, or use the memcpy() function:
for( int i = 0; i < VERTEX_NUM; i++ )
for( int j = 0; j < VERTEX_NUM; j++ )
graph->matrix[i][j] = ADJ_MATRIX[i][j];
or
memcpy( graph->matrix, ADJ_MATRIX, VERTEX_NUM * VERTEX_NUM * sizeof(int) );
Arrays are not assignable. You can use memcpy:
memcpy(graph->matrix, ADJ_MATRIX, sizeof(graph->matrix));
You cannot assign an array to another array. You will need to copy the elements from the source to the destination index by index, or use memcpy to copy the data. Array assignment like this is not allowed
You are trying to assign your variable address of a constant data,
try using
memcpy(graph->matrix,ADJ_MATRIX,sizeof(ADJ_MATRIX));//using sizeof(graph->matrix) is safer.
You can't use an array in assignments. You may use cycles or memcpy instead
memcpy(graph->matrix, ADJ_MATRIX, VERTEX_NUM * VERTEX_NUM * sizeof(int));
or
for(int i = 0; i < VERTEX_NUM; ++i){
for(int j = 0; j < VERTEX_NUM; ++j){
graph->matrix[i][j] = ADJ_MATRIX[i][j];
}
}
The error is thrown, because int matrix[VERTEX_NUM][VERTEX_NUM] in a structure definition means that each structure will have a 2D array of integers of the predefined size and matrix is going to be pointing to its first element. The thing is that matrix cannot be assigned to an arbitrary address, because it's a const pointer i.e. its value (the address it's pointing to) cannot change.
You have 2 options here: you can either use memcpy or some stl algorithms to copy the ADJ_MATRIX into matrix directly or you can declare matrix as a pointer and do the assignment that is currently produces an error.
The latter can be done in the following way:
typedef struct {
int vertex;
const int (*matrix)[VERTEX_NUM];
int vNum;
int eNum;
}Graph;
Thus you can do graph->matrix = ADJ_MATRIX assignment, but you won't be able to modify the individual items in matrix due to constness. This means, graph->matrix[0][1] = 3; is not allowed, while you can read the elements freely.

Array Initialization from a struct

I was wondering if there was a way to initialize an array out of a variable from a struct. Say you have a struct like this-
struct Test{
int Number;
};
And you wanted to initialize the int Number to become an array.
I've already tried this, and it doesn't work:
Test t1;
t1.Number = new int[3];
t1.Number[3] = 6;
I know ISO C++ forbids resizing arrays, but if there was a way to initialize the integer to be an array, that's not really resizing(isn't it?)
Also, vectors don't work inside of structs. I get a "Vector does not name a type" error.
P.S., I can't do this either:
struct Test{
int Number[5];
};
Because at that time I don't know the size of the array I want.
vector works just fine in structs:
#include <vector>
struct Test {
std::vector<int> Numbers;
};
I'm not sure what you're really trying to do but I think this comes close.
One trick to do this
struct Test {
int Numbers[1];
};
when you initialize the struct, you need to use your own allocation function.
struct Test *NewTest(int sizeOfNumbers) {
return (struct Test*)malloc(sizeof(struct Test) + sizeof(int)*(sizeOfNumbers - 1));
}
then, you will be able to access the numbers by using,
struct Test *test1 = NewTest(10);
test1->Numbers[0]...
test1->Numbers[1]...
test1->Numbers[9]...
The return value of new int[3] is an int* not an int. To make your code work you can do:
struct Test {
int* Number;
};
int main() {
Test t1;
t1.Number = new int[4]; // Note this should be 4 so that index 3 isn't out of bounds
t1.Number[3] = 6;
delete t1.Number;
return 0;
}
However you should really use a std::vector rather than a static array. Vectors work just fine inside structs:
#include <vector>
struct Test {
std::vector<int> Number;
};
int main() {
Test t1;
t1.Number.resize(4);
t1.Number[3] = 6;
return 0;
}
You can use a pointer to int -- i.e.,
struct Test{
int *Number;
};
Then you can assign this at any future time to point to an array of your preferred size:
t.Number = new int[5];
But as other posters have already said, std::vector, with a small "v", works fine; be sure to #include <vector> so the compiler knows what you're talking about.