Here I have a very simple program. My aim is to let b equal c, that is to copy all the content of c into b. But I don't know how. The getdata() function returns a pointer pointing to array of objects c, but how can it be used to put c into b?
#include<iostream>
#include<stdlib.h>
using namespace std;
class A
{
public:
A(int i,int j):length(i),high(j){}
int length,high;
};
class B
{
private:
A c[3] = {A(9,9),A(9,9),A(9,9)};
public:
A* getdata()
{
return c;
}
};
int main()
{
A b[3]={A(0,0),A(0,0),A(0,0)};
B *x = new B();
cout<< x->getdata() <<endl;
cout << b[1].length<<endl;
return 0;
}
In modern C++, make yourself a favor and use a convenient container class to store your arrays, like STL std::vector (instead of using raw C-like arrays).
Among other features, std::vector defines an overload of operator=(), which makes it possible to copy a source vector to a destination vector using a simple b=c; syntax.
#include <vector> // for STL vector
....
std::vector<A> v; // define a vector of A's
// use vector::push_back() method or .emplace_back()
// or brace init syntax to add content in vector...
std::vector<A> w = v; // duplicate v's content in w
That's a possible partial modification of your code, using std::vector (live here on codepad):
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A(int l, int h) : length(l), high(h) {}
int length, high;
};
class B
{
private:
vector<A> c;
public:
const vector<A>& getData() const
{
return c;
}
void setData(const vector<A>& sourceData)
{
c = sourceData;
}
};
int main()
{
vector<A> data;
for (int i = 0; i < 3; ++i) // fill with some test data...
data.push_back(A(i,i));
B b;
b.setData(data);
const vector<A>& x = b.getData();
for (size_t i = 0; i < x.size(); ++i) // feel free to use range-for with C++11 compilers
cout << "A(" << x[i].length << ", " << x[i].high << ")\n";
}
Instead of creating an array of A i.e. 'b' in main, create a pointer to A. And then initialize it by calling the getdata().
A *b;
B *x = new B();
b = x->getdata();
Here is an example
#include <iostream>
#include <algorithm>
class A
{
public:
A( int i, int j ) : length( i ), high( j ){}
int length, high;
};
class B
{
private:
A c[3] = {A(9,9),A(9,9),A(9,9)};
public:
A* getdata()
{
return c;
}
};
int main()
{
A b[3] = { A(0,0), A(0,0), A(0,0) };
B *x = new B();
A *c = x->getdata();
std::copy( c, c + 3, b );
for ( const A &a : b ) std::cout << a.length << '\t' << a.high << std::endl;
delete []x;
return 0;
}
The output is
9 9
9 9
9 9
Instead of standard algorithm std::copy you may use an ordinary loop. For example
for ( size_t i = 0; i < 3; i++ ) b[i] = c[i];
Related
Trying to pass array of struct pointers to function doIt() . Looks my way is not correct since I can't get right second array element:
struct c {
int a;
char* b;
};
struct cc {
int a;
c* b;
};
char a[] = "aaa";
char b[] = "bbb";
char e[] = "eee";
c d1 = {1,a};
c d2 = {2,b};
c d3 = { 12,e };
cc g1 = { 123, &d1 };
cc g2 = { 321, &d2 };
cc g3 = { 333, &d3 };
void doIt( c * s)
{
cout << s->b;
s++;
cout << s->b;
}
What is right way to pass array of struct pointers?
Raw arrays in C (and C++) are just pointers. They point to the first element of an array. For example, if you want an array of int, you would write it like int* array. If you want an array of struct c, you would write it like c* array. If you want an array of pointers to struct c, you would write it like c** array.
To access elements, don't use array++, use array[i] where i is the index (position) of the element you want to access, 0 being the index of the first element, 1 the second, etc.
So, your code should look like this:
void doIt(c** s)
{
cout << s[0]->b; // s[0] is the first element
cout << s[1]->b; // s[1] is the second
}
Note that in C++, it is preferred to use std::vector instead of raw arrays.
void doIt(std::vector<c*> s)
{
cout << s[0]->b;
cout << s[1]->b;
}
If you want to pass array to a function you need also pass length of this array:
#include <iostream>
#include <vector>
struct c {
int a;
char* b = nullptr;
size_t size = 0;
};
void doIt(c* all, size_t length);
int main()
{
char a[] = "aaa";
const size_t sizeOfA = sizeof(a)/sizeof(a[0]);
char b[] = "bbb";
const size_t sizeOfB = sizeof(b)/sizeof(b[0]);
char e[] = "eee";
const size_t sizeOfE = sizeof(e)/sizeof(e[0]);
c d1 {1, a, sizeOfA};
c d2 {2, b, sizeOfB};
c d3 {12, e, sizeOfE};
c all[] = {d1, d2, d3};
const size_t length = sizeof(all)/sizeof(all[0]);
doIt(all, length);
return 0;
}
void doIt(c* all, size_t length)
{
if (!all)
{
std::cerr << "Pointer to array is null" << std::endl;
}
for (size_t i = 0; i < length; ++i)
{
for (size_t j = 0; j < all[i].size; ++j)
{
std::cout << all[i].b[j];
}
std::cout << std::endl;
}
}
You can use std::vector. So, you don't need to use adittional argument (length of the vector):
#include <iostream>
#include <vector>
#include <string>
struct c {
int a;
std::string b;
};
void doIt(const std::vector<c>& myVector);
int main()
{
std::vector<c> myVector;
myVector.emplace_back(1, "aaa");
myVector.emplace_back(2, "bbb");
myVector.emplace_back(12, "eee");
doIt(myVector);
return 0;
}
void doIt(const std::vector<c>& myVector)
{
for (size_t i = 0; i < myVector.size(); ++i)
{
std::cout << myVector[i].b << std::endl;
}
}
I have recently started working with shared pointers and need some help. I have a vector 1 of shared pointers to some objects. I need to construct another vector 2 of shared pointers to the same objects, so that modifying vector 2 would result in modification of vector 2.
This is how my code looks like:
This works fine
class A
{
public:
int a;
A (int x) {
a = x;
}
int print() {
return a;
}
};
int main()
{
shared_ptr<A> ab = make_shared<A>(100);
cout<< ab->print();
shared_ptr<vector<shared_ptr<A>>> vec1 = make_shared<vector<shared_ptr<A>>>(1);
shared_ptr<vector<shared_ptr<A>*>> vec2 = make_shared<vector<shared_ptr<A>*>>();
vec2->push_back(&(*vec1)[0]);
for (shared_ptr<A>* obj : *vec2) {
*obj = make_shared<A>(100);
}
cout << (*((*vec1)[0])).a; // Prints 100
return 0;
}
But this gives a SEGV at the last line since vec1 is not populated:
class A
{
public:
int a;
A (int x) {
a = x;
}
int print() {
return a;
}
};
int main()
{
shared_ptr<vector<shared_ptr<A>>> vec1 = make_shared<vector<shared_ptr<A>>>(1);
shared_ptr<vector<shared_ptr<A>>> vec2 = make_shared<vector<shared_ptr<A>>>();
vec2->push_back((*vec1)[0]);
for (shared_ptr<A> obj : *vec2) {
obj = make_shared<A>(100);
}
cout << (*((*vec1)[0])).a; // SIGSEGV
return 0;
}
I want to understand why vec1 was not populated in the 2nd one and also would like to know if there is any other way of doing this. Thanks!
The code for the setup described in the comments could be:
#include <vector>
#include <memory>
#include <iostream>
using namespace std;
struct A
{
int a;
A(int a): a(a) {}
};
int main()
{
auto p_vec1 = make_shared<vector<shared_ptr<A>>>();
auto p_vec2 = make_shared<vector<shared_ptr<A>>>();
for (int i = 0; i < 100; ++i)
p_vec1->push_back( make_shared<A>(i) );
for (int i = 0; i < 50; ++i)
p_vec2->push_back( (*p_vec1)[i * 2] );
(*p_vec1)[2]->a = 213;
std::cout << (*p_vec2)[1]->a << '\n'; // print 213
return 0;
}
In case you are unaware, the "outer" shared_ptr is unnecessary, you could just use two vectors .
I would like to write a program in C++ which contains an array of function pointers.
Here is the code:
#include <iostream>
using namespace std;
class MyClass {
int a, b;
public:
MyClass(int i, int j) : a(i), b(j) {}
int add() { return a + b; }
int sub() { return a - b; }
};
void func(int (MyClass::* funcPtr[])(), MyClass& a, int i) {
if (i == 0) {
funcPtr[i] = &MyClass::add;
funcPtr;
}
if (i == 1) {
funcPtr[i] = &MyClass::sub;
funcPtr;
}
cout << " Result: " << (a.*funcPtr[i])() << endl;
}
int main(){
int auswahl = 0;
int i = 4, j = 5;
cout << "Which function? [0]-Add [1]-Substract\n";
cin >> select;
MyClass a(i,j);
func(NULL, a, select);
}
After playing around a lot I got the program to compile successfully. But it throws "Write Access Violation" on running.
The problem seems to be related to:
funcPtr[i] = &MyClass::add;
funcPtr[i] = &MyClass::sub;
It'd be very nice, if you could help me solve the problem.
Thank you so much and have a happy time!
As you pass NULL or nullptr in your function, so this line:
funcPtr[i] = &MyClass::add;
Is writing at index i into a null array!
You'd have to provide an array for your function to write into:
MyClass a(i,j);
int (MyClass::* funcPtr[2])();
func(funcPtr, a, select);
Note that using std::array instead of c-style array would avoid this problem, since they are not nullable:
void func(std::array<int (MyClass::*)(), 2> funcPtr, MyClass& a, int i) {
// ...
}
// ...
std::array<int (MyClass::*)(), 2> funcPtr;
func(funcPtr /* cannot pass null */, a, i);
This question already has an answer here:
Initializing an std::array of non-default-constructible elements?
(1 answer)
Closed 2 years ago.
I want to initialize a array of 1 million objects on stack, I need to write one million &i in the following code.
Is there any other good way.
#include <iostream>
class A{
public:
A(int* p)
: p_(p){
std::cout << "A" << std::endl;
}
private:
int *p_;
};
int main(){
int i;
A a[3] = {&i, &i, &i};
}
#include <iostream>
#include <type_traits>
class A{
public:
A(int* p)
: p_(p){
std::cout << "A" << std::endl;
}
private:
int *p_;
};
int main(){
using elemType = std::aligned_storage<sizeof(A), alignof(A)>::type;
const size_t count = 1000000;
int i;
elemType a[count];
for(int idx = 0; idx < count: ++idx) {
new (&a[idx]) A(&i);
}
...
for(int idx = 0; idx < count: ++idx) {
reinterpret_cast<A&>(a[idx]).~A();
}
return 0;
}
C++ new operator can be used to call constructor on a preallocated memory:
#include <iostream>
#include <cstddef>
#include <cstdint>
class A{
public:
A(int* p)
: p_(p){
std::cout << "A" << std::endl;
}
private:
int *p_;
};
int main(){
int i;
uint8_t buf[1000000 * sizeof(A)];
A* pa = reinterpret_cast<A*>(buf);
for (size_t n = 0; n < 1000000; n++) {
new (&pa[n]) A(&i);
}
return 0;
}
You could use std::vector and initialize is with a million elements
std::vector<A> a(1000000, &i);
I am trying to access the elements of a virtual function which is declared in Class 1 and then defined in Class 2. I understand that the std :: out_of_range error is a memory access problem, but I don't understand the problem in the code main () to access the values.
When calling the function ** m-> function (t, j) ** I cannot access the elements of * parmem *, but if I directly call the output of the function it works: ** parmem.at (1). gamma **. Here is the code:
Class 1:
#include <armadillo>
#include <iostream>
using namespace std;
using namespace arma;
class Class1
{
public:
mat Y;
struct Par
{
mat gamma;
} par;
std::vector<Par> parmem ;
virtual double function( const int t, const int j ) = 0;
};
Class 2:
class Class2 : public Class1
{
public:
virtual double function( const int t, const int j );
};
double Class2::function( const int t, const int j )
{
cout << parmem.at(t).gamma << endl;
return j+t;
}
main()
int main()
{
mat Y=randu<mat>(3,3);
int t=1;
int j=1;
Class2 *m = new Class2;
std::vector<Class1::Par> parmem {
{Y},
{2*Y}
};
cout << parmem.at(1).gamma << endl; //funciona
cout << m->function(t,j) << endl; //no funciona
return 0;
}
Thanks for the info.
In the following lines, you create independent objects:
Class2 *m = new Class2;
std::vector<Class1::Par> parmem {
{Y},
{2*Y}
};
The std::vector<Class1::Par> parmem {{Y},{2*Y}}; is not part of the instance of the object m is pointing at.
It should work if you assign parmem to the object m points on by adding m->parmem = paramen; to the code.
int main()
{
mat Y=randu<mat>(3,3);
int t=1;
int j=1;
Class2 *m = new Class2;
std::vector<Class1::Par> parmem {
{Y},
{2*Y}
};
m->parmem = paramen;
cout << parmem.at(1).gamma << endl; //funciona
cout << m->function(t,j) << endl; //no funciona
return 0;
}