Changing original vector does not change it in a collection - c++

Why do I get different output? How can I fix this? I want the trainingVector[0] to reference A.
vector<double> A(4,0);
vector<vector<double > > trainingVector;
A[0]=1;
trainingVector.push_back(A);
A[0]=2;
cout << A[0] << endl ;
cout << trainingVector[0][0] << endl ;

You cannot store references in STD containers, so what you ask for is impossible. If you want trainingVector to store a pointer to A, that's entirely doable:
vector<double> A(4,0);
vector<vector<double>*> trainingVector;
A[0] = 1;
trainingVector.push_back(&A);
A[0] = 2;
// notice that you have to dereference trainingVector[0] to get to A
cout << (*trainingVector[0])[0] << endl; // prints 2

You could store a pointer to A instead:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> A(1);
A[0] = 1;
std::vector<std::vector<int>*> trainingVector;
trainingVector.push_back(&A);
A[0] = 2;
std::cout << A[0] << std::endl;
std::cout << (*trainingVector[0])[0] << std::endl;
return 0;
}
Alternatively, if you really want the syntax as specified in the question, you could do something like this:
#include <iostream>
#include <vector>
template <typename T>
class VecRef
{
private:
std::vector<T> *m_v;
public:
VecRef(std::vector<T>& v)
: m_v(&v)
{}
T& operator[](int i)
{
return (*m_v)[i];
}
};
int main()
{
std::vector<int> A(1);
A[0] = 1;
std::vector<VecRef<int>> trainingVector;
trainingVector.push_back(A);
A[0] = 2;
std::cout << A[0] << std::endl;
std::cout << trainingVector[0][0] << std::endl;
return 0;
}

Related

c++11 - zero-initi of members insted of default-init

In the below code, I expect members of a being inited with gargabe as they are not mentioned in the members-init-list of the called constructor (with two int parameters). Instead, I'm constantly getting 0 in both i and j of a, b and c and I am failing to see why. Could anybody please point me in the right direction?
#include <iostream>
#include <type_traits>
class A {
public:
int i;
int j;
A() = delete;
A(int a, int b) { std::cout << "VOLOLO!" << std::endl; };
};
int
smear_stack(int p)
{
int j = p++;
int a[500] = {};
for(int i = 0; i < 499; i++) {
a[i] = ++j;
}
std::cout << j << std::endl;
return ++j;
}
int main(void)
{
int i = 2;
i = smear_stack(++i);
A a (i, 32 );
std::cout << "a is " << a.i << " " << a.j << std::endl;
A b = { a };
std::cout << "b is " << b.i << " " << b.j << std::endl;
A c = { a.i, a.j };
std::cout << "c is " << c.i << " " << c.j << std::endl;
}
The i and j fields that you are accessing are, indeed, uninitialized. However, you are smearing the wrong part of the stack. It just so happens that on most OSes, the stack is initially all zeros. It even used to be common in C (long ago) to assume that automatic variables in main were zero-initialized.
To see that the memory is indeed uninitialized, it suffices to put something else there. Here's an example:
#include <iostream>
#include <memory>
class A {
public:
int i;
int j;
A() = delete;
A(int a, int b) { std::cout << "VOLOLO!" << std::endl; };
};
union U {
int is[2];
A a;
U() : is{3,4} {}
};
int
main()
{
U u;
std::construct_at(&u.a, 5, 6);
std::cout << u.a.i << ", " << u.a.j << std::endl;
// output:
// VOLOLO!
// 3, 4
}

Getting segmentation fault (core dumped) error when declaring a int variable

I was trying to create vector like class. Here is my code
#include <bits/stdc++.h>
using namespace std;
template<class t>
class vec{
t *start;
int size=0;
public:
void add_value(t a){
*(start+(sizeof(t)*size)) = a;
cout << (start+(sizeof(t)*size))<< " = "<< *(start+(sizeof(t)*size))<<endl;
size++;
// cout << start<< endl;
}
void operator [](int i){
cout << (start+(sizeof(t)*i))<< " = "<< *(start+(sizeof(t)*i))<<endl;
}
int length(){
return size;
}
};
int main(){
vec<int> t;
cout << t.length()<<endl;
t.add_value(8);
t.add_value(10);
cout << t.length()<<endl;
t[1];
}
This gives me correct output.
0
0x7fff0fe9b5d0 = 8
0x7fff0fe9b5e0 = 10
2
0x7fff0fe9b5e0 = 10
But when declare a int variable in main function like.
int main(){
int i=0; //newline
vec<int> t;
cout << t.length()<<endl;
t.add_value(8);
t.add_value(10);
cout << t.length()<<endl;
t[1];
}
output.
0
Segmentation fault (core dumped)
I also tried printing address of start variable and new int variable int those are different.
You probably want something like this:
#include <iostream>
using namespace std;
template<class t>
class vec {
t* start = new t[100]; // initialize the pointer (fixed size of 100, to be improved)
int size = 0;
public:
void add_value(t a) {
*(start + size) = a;
size++;
}
t operator [](int i) { // should return a t instead of a void
return *(start + i);
}
int length() {
return size;
}
};
int main() {
vec<int> t;
cout << "t.length() = " << t.length() << endl;
t.add_value(8);
t.add_value(10);
cout << "t.length() = " << t.length() << endl;
// display all values in t
for (int i = 0; i < t.length(); i++)
{
cout << "t[" << i << "] = " << t[i] << endl;
}
}
All multiplication by sizeof(t) have been removed, because pointer arithmetic already does this for you.
This very poor and minimalist example works as you expect, but the maximum number of elements you can store in the class is 100. I leave the improvement as an exercise to you.
BTW there are many other improvements you need to do, especially you need a destructor and possibly the rule of three
Note:
You should replace all instances of *(start + x) with start[x] which does exactly the same thing but which is more idiomatic and more readable.

Pass reference of array of objects to function

I'm trying to change a parameter of an object inside an array, but it seems like it's creating a new one when I pass it to the function.
I already saw similar questions and answers like this one, but it doesn't work for me, because I don't have a fixed array size in the final code.
I created a very short version of the code to show the problem.
#include <iostream>
using namespace std;
class Vect {
public:
Vect(int x, int y)
{
_x = x;
_y = y;
}
int _x;
int _y;
};
void ChangeX(Vect tests[], int size)
{
for (int i = 0; i < size; i++) {
tests[i]._x = 39;
}
}
int main()
{
Vect v1 = Vect(1,2);
Vect v2 = Vect(6,3);
cout << "Initial X: ";
cout << v1._x;
cout << "\n";
Vect vectors[2] = { v1, v2 };
cout << "Final X: ";
ChangeX(vectors, 2);
cout << v1._x;
return 0;
}
I expect the output to be:
Initial X: 1
Final X: 39
But in reality is:
Initial X: 1
Final X: 1
Also, using C++ vectors is not the solution for now. I'm running low on program memory usage and have a very small space for extra code.
Your issue has nothing to do with your function. It is updating the contents of the array correctly. There is no need to pass the array itself by reference.
The real problem is with the array itself. The statement Vect vectors[2] = {v1, v2}; makes copies of the v1 and v2 objects in the array. Your function is modifying the copies, and then afterwards you output values from the originals instead of the copies. So, your output does not change, since the function is not modifying the originals.
To accomplish what you are attempting, pass in an array of pointers instead, where the pointers are pointing at the original objects, not copies of them, eg:
#include <iostream>
class Vect {
public:
Vect(int x, int y){
_x = x;
_y = y;
};
int _x;
int _y;
};
void ChangeX(Vect* tests[], int size){
for(int i = 0; i < size; i++){
tests[i]->_x = 39;
}
}
int main()
{
Vect v1(1,2);
Vect v2(6,3);
std::cout << "Initial X:\n";
std::cout << v1._x << "\n";
std::cout << v2._x << "\n";
Vect* vectors[2] = {&v1, &v2};
ChangeX(vectors, 2);
std::cout << "Final X:\n";
std::cout << v1._x << "\n";
std::cout << v2._x << "\n";
return 0;
}
Live Demo
Otherwise, start out with an array to begin with, eg:
#include <iostream>
class Vect {
public:
Vect(int x, int y){
_x = x;
_y = y;
};
int _x;
int _y;
};
void ChangeX(Vect tests[], int size){
for(int i = 0; i < size; i++){
tests[i]._x = 39;
}
}
int main()
{
Vect vectors[2] = {Vect(1,2), Vect(6,3)};
std::cout << "Initial X:\n";
std::cout << vectors[0]._x << "\n";
std::cout << vectors[1]._x << "\n";
ChangeX(vectors, 2);
std::cout << "Final X:\n";
std::cout << vectors[0]._x << "\n";
std::cout << vectors[1]._x << "\n";
return 0;
}
Live Demo

Get space for array with malloc

Trying to pass pointer for array:
class aaa{
public:
int a ;
int b ;
std::string c ;
};
void abc(aaa* a [])
{
*a = (aaa*)malloc(sizeof(aaa)* 5);
a[0]->c ="ddd" ;
a[1]->c ="ccc" ; //crash
a[2]->c ="eee" ;
}
int main() {
aaa * a;
abc(&a);
cout << "!!!Hello World!!!"<< a++->c << endl;
cout << "!!!Hello World!!!"<< a++->c << endl;
return 0;
}
On second array element assignment I have crash. Where is the problem? Does malloc not creates enough space?
UPD.
I can't change function void abc(aaa* a []) signature because of some reason. It is not mistakable signature even it looks not nice.
I have updated program according recomendations in answers, but I still have crash in getting second array element member:
cout << "!!!Hello World!!!"<< a[1].c << endl;
Why? What I do wrong in code below?
struct aaa{
public:
int a ;
int b ;
std::string c ;
};
int abc(aaa* a [])
{
int asize =5;
*a = (aaa*)malloc(sizeof(aaa) * asize);
for (int i;i<asize;i++)
{
a[i] = new aaa();
}
a[0]->c ="ddd" ;
a[1]->c ="ccc" ;
a[2]->c ="eee" ;
return asize;
}
int main() {
aaa * a;
int asize=abc(&a);
cout << "!!!Hello World!!!"<< a[0].c << endl;
cout << "!!!Hello World!!!"<< a[1].c << endl; //crash
cout << "!!!Hello World!!!"<< a[2].c << endl;
for (int i=0; i<asize;i++)
{
cout << "free "<<i<<endl;
a[i].~aaa();
}
free(a);
cout << "end"<<endl;
return 0;
}
The problems are multifold:
mallocing non-POD types so their constructors don't run (catastrophic)
Failure to free the things you malloc (bad)
mallocing in C++ at all (not stylish)
Passing aaa* a[] when you meant aaa** a (valid but misleading)
No #includes, or namespace qualifier on cout and endl (invalid testcase)
Here's what your program should look like:
#include <vector>
#include <string>
#include <iostream>
class aaa
{
public:
int a;
int b;
std::string c;
};
std::vector<aaa> abc()
{
std::vector<aaa> result;
result.reserve(3);
result.push_back({0, 0, "ddd"});
result.push_back({0, 0, "ccc"});
result.push_back({0, 0, "eee"});
return result;
}
int main()
{
const auto a = abc();
std::cout << "!!!Hello World!!!"<< a[0].c << std::endl;
std::cout << "!!!Hello World!!!"<< a[1].c << std::endl;
std::cout << "!!!Hello World!!!"<< a[2].c << std::endl;
}
(Live demo)
Or, to keep your five up-front element allocations:
std::vector<aaa> abc()
{
std::vector<aaa> result(5);
result[0].c = "ddd";
result[1].c = "ccc";
result[2].c = "eee";
return result;
}
I strongly suggest forgetting everything you know about C, when you write C++.
You can use malloc, but you still need to call constructors, for this you need new, this defeats idea of using malloc.
const int asize = 5;
void abc(aaa*& a)
{
a = (aaa*)malloc(sizeof(aaa) * asize); // you need to release memory later
for (int i = 0; i < asize; ++i) {
new (a+i) aaa(); // you need to call constructors to intialize string
}
// now you can use strings
a[0].c = "ddd";
a[1].c = "ccc";
a[2].c = "eee";
}
int main() {
aaa * a;
abc(a);
cout << "!!!Hello World!!!" << a[0].c << endl;
cout << "!!!Hello World!!!" << a[1].c << endl;
// finally you need to call destructors
for (int i = 0; i < asize; ++i) {
a[i].~aaa();
}
free(a);
return 0;
}
After showing you how you can make it work, i would like to propose another solution. If you care about memory and don't want to use std::vector, you can use std::unique_ptr.
std::unique_ptr<aaa[]> data;
data = std::make_unique<aaa[]>(asize);
data[0].c = "text";
cout << data[0].c;
// no need to manually release memory
EDIT:
As of updated question. If you really want to pass array of pointers then you can do the following:
const int asize = 5;
void abc(aaa* a[]) {
// If array is really big, then you probably should preallocate memory and call placement new for every element.
for (int i = 0; i < asize; ++i) {
a[i] = new aaa; // again, you have to release memory
}
// now you can use strings
a[0]->c = "ddd";
a[1]->c = "ccc";
a[2]->c = "eee";
}
int main() {
aaa * a[asize];
abc(a);
cout << "!!!Hello World!!!" << a[0]->c << endl;
cout << "!!!Hello World!!!" << a[1]->c << endl;
for (int i = 0; i < asize; ++i) {
delete a[i];
}
return 0;
}
It would be very nice if you could use unique_ptr instead of raw pointer.

how do I get sequence of 'false' in an array

I am the beginner of C++, and any help will be very appreciated.
here is the code i can run successfully:
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
main(){
bool findIn=false;
RowVectorXd A(10);
A<<false,true,false,true,true,false,false,false,true,true;
std::cout << A << std::endl;
for (int i=0;i<A.size();i++){
if(A(i)==findIn){
std::cout << i << std::endl;
}
}
system("pause");
}
the result is {0,2,5,6,7}, and I want to design a function, the code is as follows:
int seq(bool findIn, VectorXd &resdX){
VectorXd A;
for(int i=0;i<resdX.size();i++){
if(resdX(i)==findIn){
A =A+i;
}
}
return(A);
}
I want this function to return result like that {0,2,5,6,7}.But I don`t know how to set up a array to save the result or is there a function just like 'which' in R software to produce sequence above.
Sounds like you want a vector of integers:
#include <vector>
std::vector<int> seq(bool findIn, VectorXd &resdX)
{
std::vector<int> v;
for(int i=0;i<resdX.size();i++) {
if (resdX(i) == findIn) {
v.push_back(i);
}
}
return v;
}
You can then print its contents by iterating through it:
std::vector<int> result = seq(false, A);
for (int i : result) std::cout << i << '\n';
I did not understand what are you looking for.
If you want just to print a sequence of integers indexing findIn values you might code:
void seq(bool findIn, VectorXd &resdX) { // not int
std::cout << "{ ";
for(int i=0;i<resdX.size();i++) // go inside the array
if(resdX(i)==findIn) // if you find that resdX(i) value equals findIn value
std::cout << i << " "; // print i index
std::cout << "}" << std::endl; // at the end prints a new line
}
EDIT1:
Try to adapt the following snippet:
#include <list>
...
std::list<int> seq(bool findIn, VectorXd& resdX) {
std::list<int> l;
for(int i=0; i<resdX.size(); i++) {
if (resdX(i) == findIn) {
l.push_back(i);
}
}
return l;
}
void print_seq(std::list<int> list_) {
std::cout << "{ ";
std::list<int>::iterator it = list_.begin();
for (; it != list_.end(); ++it) {
std::cout << i << " ";
}
std::cout << " }\n";
}