I'm trying to use boost to create a multidimensional array and I want said array to be a member of some class.
However I find two problems with it:
1 - I need to declare the size of the array with
boost::extents[2][2]
Everytime I want to use the array. Otherwise I get the following error:
a.out: /usr/include/boost/multi_array/base.hpp:136: Referenceboost::detail::multi_array::value_accessor_n<T, NumDims>::access(boost::type<Reference>, boost::detail::multi_array::value_accessor_n<T, NumDims>::index, TPtr, const size_type*, const index*, const index*) const [with Reference = boost::detail::multi_array::sub_array<double, 1ul>; TPtr = double*; T = double; long unsigned int NumDims = 2ul; boost::detail::multi_array::value_accessor_n<T, NumDims>::index = long int; boost::detail::multi_array::multi_array_base::size_type = long unsigned int]: Assertion `size_type(idx - index_bases[0]) < extents[0]' failed.
2 - Ok, maybe this is just part of how multidimensional arrays work in C++ with Boost, I'm going to write my code accepting every function "declares" the array. However, if I do this I find the array is empty.
Here's a snippet of code that reproduces this problem. During the "construction" of the class the array should be filled. However, the line
cout << "Result: " << testing.getArrayMember(0,1) << endl;
outputs "Result: 0".
#include <iostream>
#include "boost/multi_array.hpp"
typedef boost::multi_array<double, 2> dbl_array;
using namespace std;
class TestClass {
public:
dbl_array darray;
TestClass(double x);
void fillArray(double x);
double getArrayMember(int i, int j);
};
TestClass::TestClass(double x) {
dbl_array darray(boost::extents[2][2]);
cout << "Class constructor called" << endl;
fillArray(x);
}
void TestClass::fillArray(double x) {
cout << "Filling array" << endl;
dbl_array darray(boost::extents[2][2]); // Without this line, the code fails at runtime
darray[0][0] = x;
darray[1][0] = 2.0*x;
darray[0][1] = 3.0*x;
darray[1][1] = 4.0*x;
cout << "Array filled" << endl;
}
double TestClass::getArrayMember(int i, int j) {
dbl_array darray(boost::extents[2][2]); // Without this line, the code fails at runtime
return darray[i][j];
}
int main() {
TestClass testing = TestClass(5.0);
// The result is 0 in the end
cout << "Result: " << testing.getArrayMember(0,1) << endl;
return 0;
}
What am I doing wrong here?
Option 1 is to use an initialisation list:
TestClass::TestClass(double x) : darray(boost::extents[2][2]) {
cout << "Class constructor called" << endl;
fillArray(x);
}
Since otherwise the member of the class darray is created using the default constructor and not through your line
dbl_array darray(boost::extents[2][2]);
as you believe.
This is the same answers as given in initialize boost::multi_array in a class
However, I want to add the following bit, which I think it is relevant in this situation:
It might be necessary for you to generate the array after performing some kind of operation in the constructor of your class. You can achieve this using "resize" after the array has been created by the default constructor.
Ie, instead of
TestClass::TestClass(double x) {
dbl_array darray(boost::extents[2][2]);
cout << "Class constructor called" << endl;
fillArray(x);
}
you could have
TestClass::TestClass(double x) {
darray.resize(boost::extents[2][2]);
cout << "Class constructor called" << endl;
fillArray(x);
}
Related
I'm trying to find a way to get an iterator to work on a list of custom objects and a list of objects derived from that custom object. My, perhaps misguided, goal is to allow me to leave the "production" code and objects intact yet accessible from the "experimental/extended" things that I'm trying out.
Here's a pretty minimal example of what I'm trying to do.
#include <iostream>
#include <list>
using std::cout;
using std::endl;
using std::cin;
using std::list;
struct comp{
double x,y;
void print(){
cout << "x: " << x << endl;
cout << "y: " << y << endl;
}
comp(){
x = 0;
y = 0;
}
comp(double X, double Y){
x = X;
y = Y;
}
// Standard/Tested Member Functions
};
struct base{
list<comp> components;
double known, tested, variables;
void print_comps(){
for (list<comp>::iterator it = components.begin(); it != components.end(); ++it){
// Ideally, this function should work for comp1 and comp1x
// as inherited in the basex class
it->print();
}
}
// Standard/Tested Member Functions
};
struct compx : comp{
double w,z;
double some, alter, nates;
void print(){
cout << "x: " << x << endl;
cout << "y: " << y << endl;
cout << "w: " << w << endl;
cout << "z: " << z << endl;
}
compx(){
x = 0;
y = 0;
z = 0;
w = 0;
}
compx(double X, double Y, double Z, double W){
x = X;
y = Y;
z = Z;
w = W;
}
// Experimental/Un-tested Member Functions
};
struct basex : base{
list<compx> components;
double exper, imen, tal;
// void print_comps(){} // This should be inherited from base
// Experimental/Un-tested Member Functions
};
int main(){
base compilation1;
compilation1.components.push_back(comp(1,2));
compilation1.components.push_back(comp(3,4));
cout << "printing normal struct" << endl;
compilation1.print_comps();
cout << endl;
basex compilation2;
compilation2.components.push_back(compx(9, 5, 5, 6));
compilation2.components.push_back(compx(7, 2, 1, 8));
cout << "printing extended struct" << endl;
compilation2.print_comps(); // Prints nothing
cout << endl;
cout << "Printing via specific iterator" << endl;
for (list<compx>::iterator it = compilation2.components.begin(); it != compilation2.components.end(); ++it){
it->print(); // Works as expected.
}
cout << endl << endl << "Press ENTER to exit." << endl; cin.get();
return 0;
}
Ideally, I would be able to iterate over both the original class and the extended class in the same functions so I don't clutter the extended class with all the original code. This would allow me to simply move code from the extended class to the original class as those variables or functions are proven or matured.
Background:
I'm not married to lists -- any other iterable class would be fine.
I'm not a developer -- I'm a ChemE trying to make daily tasks a bit easier without breaking what I've already built.
Branches in a git repository are not a great solution because other non-developer, potentially code-challenged, folks may try to extend this. Getting them to use even one branch would be a miracle.
I'm using g++ 7.4.0 on Linux (Lubuntu) and 6.3.0 on Windows 7.
TL;DR:
Is there a way to get an iterator of list<parent_object> to also iterate over list<child_object>?
This could be solved by having base as a template http://cpp.sh/7r2x6a
template<typename T>
struct base
{
list<T> components;
double known, tested, variables;
void print_comps(){
for (auto it = components.begin(); it != components.end(); ++it){
// Ideally, this function should work for comp1 and comp1x
// as inherited in the basex class
it->print();
}
}
// Standard/Tested Member Functions
};
If you're okay with not being able to mix comp and compx objects together in the same list, then you can use a templated function to avoid duplicate code.
For example, you can do the following in your struct base:
struct base{
list<comp> components;
double known, tested, variables;
void print_comps() {print_comps_aux<comp>(components);}
protected:
template <typename CompType> void print_comps_aux(list<CompType> & compsArg)
{
for (typename list<CompType>::iterator it = compsArg.begin(); it != compsArg.end(); ++it){
it->print();
}
}
// Standard/Tested Member Functions
};
... and then in your struct basex you can just have this:
[...]
void print_comps() {print_comps_aux<compx>(components);}
I have a fair bit of experience with R, but am only now getting down to the business of learning C++, so I beg forgiveness for any ensuing stupidity....
Given the following test.cpp file:
#include <Rcpp.h>
#include <string>
using namespace Rcpp;
using namespace std;
XPtr< double > getPtr(NumericVector x) {
double i;
i = REAL(x)[0];
XPtr< double > p(&i, false);
XPtr<double> checkP(p);
double checkV = *checkP;
cout << "Values within getPtr scope:" << endl;
cout << "Pointer address " << hex << checkP << endl;
cout << "Pointer value " << checkV << endl;
return p;
}
// [[Rcpp::export]]
void testPtr(NumericVector x){
XPtr<double> p(getPtr(x));
cout << "Values outside of getPtr scope:" << endl;
cout << "Pointer address " << hex << p << endl;
cout << "Pointer value " << *p << endl;
return;
}
The following R snippet demonstrates that the value pointed to by the Xptr "disappears" outside the getPtr function.
> library(Rcpp)
> Rcpp::sourceCpp(file="test.cpp")
>
> test <- c(35,28,16,52)
> testPtr(test)
Values within getPtr scope:
Pointer address 0x7ffd3763d790
Pointer value 35
Values outside of getPtr scope:
Pointer address 0x7ffd3763d790
Pointer value 6.95277e-310
But of course! Since that value is out of scope, this is expected behavior.
Alternatively, if I wrap the value in a class and use new, the object persists and I can retrieve my value outside the scope of the called function:
class Wrap {
public:
Wrap(double x) {
i = x;
}
double i;
};
XPtr< Wrap > getPtrW(NumericVector x) {
double i;
i = REAL(x)[0];
Wrap* w = new Wrap(i);
XPtr< Wrap > p(w, true);
return p;
}
// [[Rcpp::export]]
void testWrappedPtr(NumericVector x){
XPtr<Wrap> wp(getPtrW(x));
Wrap w = *(wp);
cout << "Wrapped value " << w.i << endl;
return;
}
Then this demonstrates that the value persists as desired:
> testWrappedPtr(test)
Wrapped value 35
My questions (at last) are these: (1) Is this (i.e. wrapping in a class) the only way to hang on to values of variables that are fundamental types and not malloc'd or new'd and (2) if not, are any of the alternative ways "better" or "preferred"?
Thanks in advance!
I'm trying to figure out how I can or why I can't access the member of this class. First I'll show you what works so you know what I'm thinking, then I'll show you what I can't seem to do.
What I can do is this: I have a class with a member. I make an pointer array of that class and make NEW pieces of it (through loop) and that's fine and all. I can also make another class with a similar array and even make NEW instances of that as well and initialize them, but when I try to access them, I have problems.
This code almost works fine:
#include <iostream>
using namespace std;
class testClass{
public:
int number;
};
class testPoint{
public:
testClass testInstance;
testClass *testclassArray[5];
void makeArray();
void setToI();
};
void testPoint::makeArray(){
for (int i = 0; i < 5; i++){
testclassArray[i] = new testClass;
}
}
void testPoint::setToI(){
for (int i = 0; i < 5; i++){
(*testclassArray[i]).number = i;
}
}
int main(void){
testPoint firstTestPoint;
firstTestPoint.makeArray();
firstTestPoint.setToI();
// EXCEPT FOR THIS LINE this is where I have problems
cout << firstTestPoint.(*testclassArray[0]).number << endl;
return 0;
}
I know this should work becuase this works
int main(void){
testPoint firstInstance;
firstInstance.testInstance.number = 3;
cout << firstInstance.testInstance.number << endl;
// and this works
return 0;
}
and this works
int main(void){
testClass *testPointer[5];
for (int i = 0; i < 5; i++){
testPointer[i] = new testClass;
(*testPointer[i]).number = i;
}
cout << (*testPointer[0]).number << endl;
return 0;
}
so why can't I access the members on the cout function the same way?
The following is invalid syntax:
cout << firstTestPoint.(*testclassArray[0]).number << endl;
The most common way to write what you are trying to accomplish is:
cout << firstTestPoint.testclassArray[0]->number << endl;
But, if you prefer, you can also write:
cout << (*firstTestPoint.testclassArray[0]).number << endl;
(The second way is far less common.)
The . operator is used to access members of direct objects, e.g. a.member where a might be declared as struct A a;. The -> operator is used to access members of indirect objects (aka pointers to objects), e.g. b->member where b might be declared as struct B* b = new B();.
You are dereferencing the variable in an incorrect way.
Try doing
cout << firstTestPoint.testclassArray[0]->number << endl;
instead.
In the same way the second attempt, where it works for you, could also have been written:
out << testPointer[0]->number << endl;
Try using this code:
cout << firstTestPoint.testclassArray[0]->number << endl;
This question already has answers here:
Uninitialized values being initialized?
(7 answers)
Closed 8 years ago.
I'm doing some testing...
Firstly I post my source code
the .h file
class Complex{
private:
int r = 0;//initializer
int i ;
public:
Complex(int , int I = 0);
Complex();
void print();
void set(int, int I = 1);
static void print_count();
static int count;
};
the .cpp file
#include <iostream>
#include "complex.h"
int Complex::count = 1;
Complex::Complex(int R , int I){
r = R;
i = I;
count++;
std::cout << "constructing Complex object...count is " << Complex::count << std::endl;
}
Complex::Complex(){//default constructor
std::cout << "default constructor is called..." << std::endl;
}
void Complex::print(){
std::cout << "r = " << r << ';' << "i = " << i << std::endl;
return;
}
void Complex::set(int R, int I /*= 2*/){//will be "redefaulting", an error
r = R;
i = I;
return;
}
void Complex::print_count(){//static
Complex::count = -1;//jsut for signaling...
std::cout << "count is " << count << std::endl;
return;
}
the main function
#include <iostream>
#include "complex.h"
int main(){
Complex d;//using default constructor
d.print();
/*Complex c(4, 5);*/
Complex c(4);
//c.print();
/*c.set(2, 3)*/
c.print();
c.set(2 );
c.print();
std::cout << "count is " << c.count << std::endl;//c can access member data
c.print_count();
c.count++;//
return 0;
}
consider the Complex object d constructed with default ctor
because the data member r is initialized using with 0, when executing d.print(),
r is expected to be 0
and i isn't, so I expected it to be garbage value
but when I'm testing, one strange thing happens.
if I eliminate this and the following lines of code in the main file:
std::cout << "count is " << c.count << std::endl;//c can access member data
then d.print() will give the value of i as 32767 on my system, which I guess it's a garbage value;
but once that line is added, d.print() just give i's value to 0 on my system.
I don't get it. I hasn't set, modiify or initialize i's value, why should it be 0?
or, it is also a garbage value?
or, calling one of those function corrupts the value of i?
how is the thing run behind the scene here?
thx for helping.
0 is just as garbage value as any other. Don't make the mistake of thinking otherwise.
Formally, reading an uninitialized variable is undefined behavior, so there's no point in wondering about it: just fix it by initializing the variable properly.
My module tries to do things along the lines of the following program: sub-functions try to modify a structure's elements and give it back to the function to whom the structure is passed by reference.
#include <iostream>
#include <vector>
using namespace std;
struct a
{
int val1;
vector<int> vec1;
};
struct a* foo();
void anotherfunc(struct a &input);
int main()
{
struct a *foo_out;
foo_out = foo();
cout<< "Foo out int val: "<< foo_out->val1<<"\n";
cout<< "Foo out vector size: "<< foo_out->vec1.size()<< "\n";
cout<< "Foo out vector value1: "<< foo_out->vec1.at(0)<< "\n";
cout<< "Foo out vector value2: "<< foo_out->vec1.at(1)<< "\n";
return 0;
}
struct a *foo()
{
struct a input;
input.val1=729;
anotherfunc(input);
return &input;
}
void anotherfunc(struct a &input)
{
input.vec1.push_back(100);
input.vec1.push_back(1000);
input.vec1.push_back(1024);
input.vec1.push_back(3452);
cout<< "Anotherfunc():input vector value1: "<< input.vec1.at(0)<< "\n";
cout<< "Anotherfunc():input vector value2: "<< input.vec1.at(1)<< "\n";
cout<< "Anotherfunc():input int val: "<< input.val1<< "\n";
}
I am expecting the main function to contain the modified integer value in structure (729), and also the vector values (100,10000,1024 and 3452). On the contrary, main has none of these values, and on g++, the program shows a strange behaviour: main() shows that there are 4 elements in the vector inside structure, but when trying to print the values, segfaults.
After some more thought, I assume my question is : "Are structure members of structure passed by reference, passed ONLY by value ?" Should I not expect that vector to have the values set by functions to whom the entire structure is passed by reference? Kindly help.
Vijay
struct a *foo()
{
struct a input;
input.val1=729;
anotherfunc(input);
return &input;
}
You are returning pointer on the local object (it will be destroyed on exit from function), so, there is dangling pointer here and your program has undefined behaviour.
As ForeEveR says, the pointer you are returning is pointing to memory which is no longer guaranteed to contain a valid object. If you want this behavior, allocate input on the heap as follows:
a * foo ()
{
a * input = new input;
input->val1 = 729;
anotherfunc (*input);
return input;
}
Now it is the responsibility of whoever calls foo to free this memory, for example
{
a * foo_out = foo();
// do stuff with foo_out
delete foo_out; foo_out = 0;
}
At some point you will realize that keeping track of who allocated which objects is tedious, when this happens you should look up "smart pointers".
First of all, there is nothing terribly magical about "structures" in C++ — you should treat them like any other type. In particular, you don't need to write the keyword struct everywhere.
So here's your code in more idiomatic C++ (also re-ordered to avoid those wasteful pre-declarations):
#include <iostream>
#include <vector>
using namespace std;
struct a
{
int val1;
vector<int> vec1;
};
void bar(a& input)
{
input.vec1.push_back(100);
input.vec1.push_back(1000);
input.vec1.push_back(1024);
input.vec1.push_back(3452);
cout << "bar():input vector value1: " << input.vec1.at(0) << "\n";
cout << "bar():input vector value2: " << input.vec1.at(1) << "\n";
cout << "bar():input int val: " << input.val1 << "\n";
}
a* foo()
{
a input;
input.val1=729;
bar(input);
return &input;
}
int main()
{
a* foo_out = foo();
cout << "Foo out int val: " << foo_out->val1 << "\n";
cout << "Foo out vector size: " << foo_out->vec1.size() << "\n";
cout << "Foo out vector value1: " << foo_out->vec1.at(0) << "\n";
cout << "Foo out vector value2: " << foo_out->vec1.at(1) << "\n";
}
Now, as others have pointed out, foo() is broken in that it returns a pointer to a local object.
Why all the pointer trickery? If you're worried about copying that vector, then you can dynamically-allocate the a object and use a shared pointer implementation to manage that memory for you:
void bar(shared_ptr<a> input)
{
input->vec1.push_back(100);
input->vec1.push_back(1000);
input->vec1.push_back(1024);
input->vec1.push_back(3452);
cout << "bar():input vector value1: " << input->vec1.at(0) << "\n";
cout << "bar():input vector value2: " << input->vec1.at(1) << "\n";
cout << "bar():input int val: " << input->val1 << "\n";
}
shared_ptr<a> foo()
{
shared_ptr<a> input(new a);
input->val1 = 729;
bar(input);
return input;
}
Otherwise, just pass it around by value.