Vector subscript out of range when incrementing an int? - c++

So strange situation, I am creating a list of structs, and then I am trying to update one of the list members with new values, and then move it back into the list.
I seem to be able to copy the values of the struct at iterator just fine, but when I attempt to update the value of the struct's member (using int++;) it throws an exception in the vector class of all things.
Any kind of explanation as to what might be happening here would be helpful.
struct Blob
{
int x;
int y;
};
list<Blob> blob;
// Add a Blob to blob using .push_back(); here
for(list<Blob>::iterator iterator=blob.begin(); iterator!=blob.end(); ++iterator)
{
Blob temp;
temp.x = ((Blob)*iterator).x;
temp.y = ((Blob)*iterator).y;
if (temp.x < 10 - 1)
temp.x++; /* Exception: vector: line 932 - "Vector subscript out of range" */
((Rain)*iterator) = temp;
}

When you want to update the existing value of object then take a reference of it. I have written a sample code to explain the same
#include<list>
#include<iostream>
using namespace std;
struct Test
{
int x;
int y;
};
int main()
{
list<Test> lTest;
int i = 0;
for(i=0;i<5;i++)
{
Test t1;
t1.x = i;
t1.y = i*i;
lTest.push_back(t1);
}
list<Test>::iterator lIter = lTest.begin();
for(;lIter != lTest.end();++lIter)
{
Test &t1 = *lIter;
cout<<"1 Val is:"<<t1.x<<"|"<<t1.y<<endl;
t1.x += 2;
t1.y += 2;
cout<<"2 Val is:"<<t1.x<<"|"<<t1.y<<endl;
}
lIter = lTest.begin();
for(;lIter != lTest.end();++lIter)
{
Test t1 = *lIter;
cout<<"3 Val is:"<<t1.x<<"|"<<t1.y<<endl;
}
return 0;
}

If you're writing a loop it's likely there's another way to do it. You can use std::for_each:
#include <list>
#include <algorithm>
struct Blob
{
int x;
int y;
};
void incrementXIfLessThanNine(Blob& blob)
{
if(blob.x < 9)
{
blob.x++;
}
}
int main()
{
std::list<Blob> blobs;
std::for_each(blob.begin(), blob.end(), incrementXIfLessThanNine);
return 0;
}
If you're using C++11:
#include <list>
struct Blob
{
int x;
int y;
};
int main()
{
std::list<Blob> blobs;
for(Blob& blob: blobs)
{
if(blob.x < 9)
{
blob.x++;
}
}
return 0;
}

Related

C++ exception thrown

I am learning C++ and have lost quite some time trying to solve to understand the reason of the error i am getting.
When i run the code below i am getting an Exception thrown. It happens when the program ends, so i believe it's related to the Edge pointer:
#include <iostream>
#include <vector>
#include <map>
using namespace std;
struct Edge {
int src, dest;
};
class Graph {
public:
int V, E;
Edge *edge = new Edge[E * sizeof(Edge)];
Graph(int Ver, int Edg);
};
Graph::Graph(int Ver, int Edg) {
V = Ver;
E = Edg;
}
Graph* createGraph(int V, int E) {
Graph* graph = new Graph(V,E);
return graph;
}
int find(int* parents, int val) {
if (parents[val] == -1)
return val;
return find(parents, parents[val]);
}
void Union(int *parents, int x, int y) {
parents[x] = y;
}
int isCycle(Graph* graph) {
int* parents = new int[graph->V * sizeof(int)];
memset(parents, -1, graph->V * sizeof(int));
for (int i = 0; i < graph->E; i++) {
int x = find(parents, graph->edge[i].src);
int y = find(parents, graph->edge[i].dest);
if (x == y) {
return 1;
};
Union(parents, x, y);
}
return 0;
}
int main()
{
int V = 9, E = 8;
Graph* graph = createGraph(V, E);
graph->edge[0].src = 0;
graph->edge[0].dest = 1;
graph->edge[6].src = 0;
graph->edge[6].dest = 6;
graph->edge[5].src = 0;
graph->edge[5].dest = 7;
graph->edge[1].src = 1;
graph->edge[1].dest = 2;
graph->edge[2].src = 3;
graph->edge[2].dest = 2;
graph->edge[3].src = 4;
graph->edge[3].dest = 3;
graph->edge[4].src = 4;
graph->edge[4].dest = 5;
graph->edge[7].src = 5;
graph->edge[7].dest = 7;
if (isCycle(graph))
cout << "graph contains cycle";
else
cout << "graph doesn't contain cycle";
return 0;
}
I started learning C++ only few months ago, can somebody help me to understand why I am getting that exception?
Edge *edge = new Edge[E * sizeof(Edge)];
Unless E is initialized, this multiplies an uninitalized variable by sizeof(Edge) (which is also wrong on its face value as well, but we'll get to it later). This is undefined behavior.
Graph::Graph(int Ver, int Edg) {
V = Ver;
E = Edg;
}
This isn't good enough. The default values of class members, if specified, are used to initialize them before the constructor's body starts running.
The proper way to do this is to use the constructor's initialization section:
Graph::Graph(int Ver, int Edg) : V{Ver}, E{Ver}
{
}
This initializes V and E first, so now:
Edge *edge = new Edge[E * sizeof(Edge)];
So here, E is now initialized, fixing this problem. But this is still slightly incorrect. It's clear, based on the rest of the code, that this should really be:
Edge *edge = new Edge[E];
In C++, when you wish to declare an array of, say, 4 integers, all you have to do is declare:
int n[4];
The compiler takes care of multiplying 4 by however many bytes it takes to hold an int. The same thing is true for the new statement. If your goal is to construct an array of #E Edges, that would be, unsurprisingly: new Edge[E]. This same mistake occurs several times in the shown code.

Modifying value of object pointed by a shared pointer

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 .

How to pass parameters in an objects of array? in c++

class A
{
int id;
public:
A (int i) { id = i; }
void show() { cout << id << endl; }
};
int main()
{
A a[2];
a[0].show();
a[1].show();
return 0;
}
I get an error since there is no default constructor.However thats not my question.Is there a way that ı can send parameters when defining
A a[2];
A good practice is to declare your constructor explicit (unless it defines a conversion), especially if you have only one parameter. Than, you can create new objects and add them to your array, like this :
#include <iostream>
#include <string>
class A {
int id;
public:
explicit A (int i) { id = i; }
void show() { std::cout << id << std::endl; }
};
int main() {
A first(3);
A second(4);
A a[2] = {first, second};
a[0].show();
a[1].show();
return 0;
}
However, a better way is to use vectors (say in a week you want 4 objects in your array, or n object according to an input). You can do it like this:
#include <iostream>
#include <string>
#include <vector>
class A {
int id;
public:
explicit A (int i) { id = i; }
void show() { std::cout << id << std::endl; }
};
int main() {
std::vector<A> a;
int n = 0;
std::cin >> n;
for (int i = 0; i < n; i++) {
A temp(i); // or any other number you want your objects to initiate them.
a.push_back(temp);
a[i].show();
}
return 0;
}

Accessing functions of a class not working

I've just started learning C++ and am complete newbie, sorry in advance if the question will sound stupid
I have my program to solve Two Sum problem:
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
vector<int> twoSum(const vector<int>& a, int target) {
unordered_map<int, int> valueToIndex;
for (int i = 0; i < (int)a.size(); i++) {
auto it = valueToIndex.find(target - a[i]);
if (it != valueToIndex.end()) {
return { it->second,i };
}
valueToIndex[a[i]] = i;
}
throw invalid_argument("sum not found");
}
};
int main()
{
vector<int> a{ 11,22,33,44,55 };
int target_value = 55;
Solution A;
A.twoSum(a,target_value);
return 0;
}
When I try to compile my program using test input values console returns nothing
What could be the issue?
Thanks!
Firstable, if you have a function that returns something, you need to get that return.
In your example, like that
vector<int> myResult = A.twoSum(a,target_value);
Then you can use that result like that.
for (const auto &value : myResult)
std::cout << value << std::endl;

Vector::push_back not storing values in vector

Recently I've been trying to write a neural network program. I have all a neurons connections stored in a vector in the neuron. However whenever I push back a connection into the vector it doesn't seem to store (I can tell via debug mode), and when I try to add up the activation values of the vectors in a for loop, I get an out_of_range error. Here's my code.
Main.cpp
#include <iostream>
#include "neuron.h"
void displayboard(bool board [8][8]);
using namespace std;
int main()
{
int id = 2;
int inputids [] = {3};
int outputids [] = {4};
int inputweights [] = {5};
bool new_neuron = true;
neuron test (inputids, outputids, inputweights, new_neuron, id);
test.connections.at(0).value = 6;
// here is where the error is returned
test.activation();
cout << test.activationnumber;
return 0;
}
And here's Neuron.cpp:
#include "neuron.h"
#include <vector>
#include <random>
#include <ctime>
using namespace std;
neuron::neuron(int inputids [], int outputids [], int inputweights [],
bool new_neuron, int id)
{
this->id = id;
if (new_neuron==true) {
srand (time(0));
connection tempconnection;
for (int i = 0; i <=(sizeof (inputids)/sizeof (inputids [0])); i++)
{
tempconnection.type=false;
tempconnection.tofrom = inputids [i];
tempconnection.weight = rand ();
this->connections.push_back (tempconnection);
}
// this continues on for other options
}
void neuron::activation (){
for (int i=0; i<=this->connections.size (); i++) {
this->activationnumber += ((this->connections.at(i).value)
*(this->connections.at (i).weight));
}
}
UPDATE: Reading this will help you understand why your "sizeof/sizeof" approach is not good in C++.
Original answer
The behavior of sizeof(array)/sizeof(array[0]) might not be what you expected. The following code outputs 2 but you seem to expect 4. Use array for objects in the stack or vector for objects in the heap.
#include <iostream>
using namespace std;
void foo( int array[] )
{
wcout << sizeof( array ) / sizeof( array[ 0 ] );
}
int main()
{
int test[ 4 ];
foo( test );
return 0;
}
Change
int inputids [] = {3};
int outputids [] = {4};
to
vector< int > {3};
vector< int > {4};
Also change
neuron(int inputids [],int outputids [] …
{
…
for (int i = 0; i <= …; i++)
…
tempconnection.tofrom = inputids [i];
to
neuron( vector< int > & inputids, vector< int > & outputids …
{
…
for( auto id : inputids )
…
tempconnection.tofrom = id;