Reputation: 33
I have an small and quite simple issue in C++. I want to fill array of struct containing double arrays. How can I do that?
typedef struct
{
double *inputs[2];
double *target[1];
} Data;
Data data[]
{
new double[2]{10, 20}, new double[1]{30},
new double[2]{40, 50}, new double[1]{60},
new double[2]{70, 80}, new double[1]{90},
new double[2]{100, 110}, new double[1]{120}
};
and in the main()
printf("data[0]: inputs: %f %f, targets: %f\n",
*data[0].inputs[0],
*data[0].inputs[1],
*data[0].target[0]);
This is my idea, but when I run that it will print this:
data[0]: inputs: 10.000000 30.000000, targets: 40.000000
Of course, at the end of the array data (like 3rd or 4th item) it will cause UNAUTHORIZED ACCESS TO MEMORY
Thank you for your ideas and patience ;)
Upvotes: 2
Views: 164
Reputation: 33092
Your problem is here:
typedef struct {
double *inputs[2]; // this
double *target[1]; // this
} Data;
This is an array of pointers and hopefully assumed to behave live a dynamic 1D array. Simple fix is:
struct Data {
double *inputs = nullptr;
double *target = nullptr;
} ;
However, you have a lot of heap memory allocation using new
, which makes a tedious task to delete
and thereby the management of your data structure really difficult.
I would strongly suggest you to use std::vector<>
, which makes your task much easier and more cleaner.
#include <vector>
#include <iostream>
struct Data
{
std::vector<double> inputs; // use instead of double *inputs[2];
std::vector<double> target; // use instead of double *target[1];
//Data(const std::vector<double>& a, const std::vector<double>& b) :inputs(a), target(b){}
};
int main()
{
std::vector<Data> data = // now in your main structure array
{ { {10, 20}, {30} },
{ {40, 50}, {60} },
{ {70, 80}, {90} },
{ {100, 110},{120} }
};
// access using range based loop now
for(const Data& each_strcut: data)
std::cout << each_strcut.inputs[0] << " " << each_strcut.inputs[1]
<<"\t" << each_strcut.target[0] << std::endl;
return 0;
}
Upvotes: 1
Reputation: 36613
Using modern c++ makes your code both simpler and safer:
#include <iostream>
#include <array>
#include <vector>
struct Data {
std::array<double,2> inputs;
std::array<double,1> target;
};
int main()
{
std::vector<Data> data = {
{ {10, 20}, {30} },
{ {40, 50}, {60} },
{ {70, 80}, {90} },
{ {100, 110}, {120} }
};
std::cout << "data[0]: inputs: " << data[0].inputs[0] << " " << data[0].inputs[1] << ", targets: " << data[0].target[0] << "\n";
}
Your original problem is that double *inputs[2]
declares a 2 element array of pointers to double
not a pointer to a 2 element array of doubles
.
Upvotes: 3
Reputation: 2850
Your Data
struct contains 2 fields, array of 2 double
pointers, and array of 1 double
pointers.
That means that initalizing it takes up to 3 double
pointers, which means that in your initalization really looks like this
Data data[]{
{new double[2]{ 10, 20 }, new double[1]{ 30 }, new double[2]{ 40, 50 }}, //1st object
{new double[1]{ 60 }, new double[2]{ 70, 80 }, new double[1]{ 90 }}, //2nd object
{new double[2]{ 100, 110 }, new double[1]{ 120 }} //3rd object but 2 parameters??
};
When trying to print it in a loop, 3rd object will cause a segfault, as target
field hasn't been properly initalized (when debugging with Visual Studio it's set to null, not sure about other compilers).
Upvotes: 1