"Cannot access memory at address" on array of vectors - c++

I am trying to make a Graph in C++, and I have almost no code, but I get some weird error. If I just run code, I get Process finished with exit code 0, but if I take a look at debugger (specifically, it I try to check my graph object), I see Cannot access memory at address 0x....
I am new to C++, so I cannot really get what has given me this error. Also, I almost don't have code yet & these few lines I took from my previous program which worked without this problem.
Anyway, I have a vertex class:
#ifndef P2_VERTEX_H
#define P2_VERTEX_H
class vertex {
private:
int id;
public:
explicit vertex(int id) { this->id = id; }
int get_id() { return id; }
};
#endif //P2_VERTEX_H
And then a graph header:
#ifndef P2_GRAPH_H
#define P2_GRAPH_H
#include <vector>
#include "vertex.h"
class graph {
private:
int N; // number of vertices
int M; // number of edges
std::vector<vertex*> vertices; // vector of vertices
std::vector<vertex*> *adj; // ARRAY of vectors of vertices
public:
graph(int n_vert);
graph(bool from_file, const char *file_name);
};
with implementation of graph:
#include "graph.h"
#include <iostream>
#include <fstream>
#include <sstream>
graph::graph(int n_vert) {
N = n_vert;
}
And I instantiate graph as:
#include "graph.h"
int main() {
graph g = graph(4);
return 0;
}
Specifically, I get this mistake if I uncomment std::vector<vertex*> *adj; in a graph header. While I realise that this is probably not the perfect way of storing adjacency list, I fail to see why it gives me an error I mentioned. Especially since I used it before, just instead of std::vector<vertex*> I had std::vector<edge*> where edge was some struct. I tried also to have std::vector<vertex> isntead of std::vector<vertex*> but I have the same error.
Upd:
If I initialize adj in constructor:
adj = new std::vector<vertex*>[N];
I get Duplicate variable object name in debugger after reaching this line.

The issue is that you never initialized adj so it will point to a random location in memory.
You have to initialize the pointer to nullptr to get rid of it.
For example, in the constructor initialization list:
graph::graph(int n_vert) : N(n_vert), adj(nullptr)
{}
By the way you forgot to initialize other field members.

Related

overloading ++ in two layer iterator produces strange bug

I wrote the following C++ code to iterate over a vector of vectors of objects. I want to iterate over every object in the vector of vectors. The code below works but it has one peculiarity I don't understand.
The line "int types_size=types->size();" is a hack employed in iterator.hpp. I don't really know the language very well so I don't know if I've found a compiler bug or if this a bug in my code. The variable "types_size" shouldn't be needed. It is used in two lines
first line:
while(s<types_size && (s<0 || (*types)[s]->size()==0 || object==&( ((*types)[s])->end()))){
second line:
if(s<types_size){
If "types_size" is replaced with "types->size()" in the first line the code will seg fault when it runs. Making the same replacement but only in the second line does not result in a seg fault. I don't understand what is going on. Any comments on the rest of this code will be appreciated.
#ifndef _iterator_hpp_
#define _iterator_hpp_
#include <vector>
using namespace std;
typedef double Object;
typedef vector<Object> ObjectVector;
class Region{
public:
vector<ObjectVector*> types;
};
class ObjectIterator{
private:
int s;
vector<ObjectVector*> *types;
protected:
public:
Object *object;
bool finished;
ObjectIterator operator++(){
if (s>=0) object++; // increments to next object
int types_size=types->size(); // this is a hack that fixes a seg fault (compiler bug??)
// *types is a vector<ObjectVector*>. (*types)[s] is the "sth" ObjectVector*.
// &(*iterator) gives a pointer to the object pointed to by iterator.
//((*types)[s])->end()) is an iterator that points past the end of
// the ObjectVector* ((*types)[s])->end())
while(s<types_size && (s<0 || (*types)[s]->size()==0 || object==&(* ((*types)[s])->end()))){
//need to increment to next non-empty types
s++;
if(s<types_size){
object=&((*(*types)[s])[0]);
}else{finished=true;}
}
return (*this);
}
/*---------------------constructor--------------------------------------------------------
start with s=-1 and increment to first object */
ObjectIterator(vector<ObjectVector*> *typesarg):finished(false) {
types=typesarg;s=-1;++(*this);
};
};
#endif
--------------------------------main--------------------------------
// it.cpp
// g++ it.pp
#include <iostream>
#include <vector>
#include "iterator.hpp"
using namespace std;
int num_types=3;
int main(){
Region region;
int num_objects[num_types];
num_objects[0]=1;
num_objects[1]=3;
num_objects[2]=5;
// create an ObjectList for each type
for(int s=0;s<num_types;s++){
ObjectVector *objectlist = new ObjectVector;
for(int i=0;i<num_objects[s];i++){
objectlist->push_back((double)2*(i+1)*(s+1));
}
region.types.push_back(objectlist);
}
cout <<"types.size="<< region.types.size()<<endl;
for(ObjectIterator OI(&region.types); !OI.finished ; ++OI)
{
cout <<*(OI.object)<<endl;
}
}
size() returns an unsigned integer so this:
while(s<types->size()
will not behave the same if s is -1 (its initial value). -1 is turned into a large unsigned integer and the comparison is false. See Signed/unsigned comparisons for more information.

array of object in C++ in sfml

I am trying to use vectors in sfml C++ and I am semi-failing because I am not able to create a vector consisting of 4 RectangleShapes :(
I am skipping some lines of the code which are not causing the problem
This is the code which is working but it is least optimized in my opinion
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <vector>
#include <iostream>
#include "mainCharacter.h" // it consists the mainCharacter class
class classBackground{
public:
sf::Texture texture;
sf::Sprite image;
sf::RectangleShape rectTopBorder,rectBotBorder,rectLeftBorder,rectRightBorder;
std::vector<sf::RectangleShape> rect;
classBackground(){
texture.loadFromFile("wagon.png");
image.setTexture(texture);
image.setPosition(300,250);
rectTopBorder.setSize(sf::Vector2f(230,5));
rectTopBorder.setPosition(image.getPosition());
rectTopBorder.move(0,60);
rectBotBorder.setSize(sf::Vector2f(230,5));
rectBotBorder.setPosition(image.getPosition());
rectBotBorder.move(0,225);
rectLeftBorder.setSize(sf::Vector2f(5,170));
rectLeftBorder.setPosition(image.getPosition());
rectLeftBorder.move(0,60);
rectRightBorder.setSize(sf::Vector2f(5,170));
rectRightBorder.setPosition(image.getPosition());
rectRightBorder.move(225,60);
rect.push_back(rectTopBorder);
rect.push_back(rectBotBorder);
rect.push_back(rectLeftBorder);
rect.push_back(rectRightBorder);
}
};
//in the main function
classMainCharacter mainCharacter; ///another class which has collision detection
classBackground background;
///in the loop
for(int i = 0; i<=3; i++){
mainCharacter.collision(background.rect[i]); ///colision is a function in the mainCharacter class (detects collision)
}
And this is the code which I want to work but my game is crushing :(
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <vector>
#include <iostream>
#include "mainCharacter.h" // it consists the mainCharacter class
class classBackground{
public:
sf::Texture texture;
sf::Sprite image;
std::vector<sf::RectangleShape> rect; // it doesn't work if I write rect(4) or rect = {rect1,rect2,rect3,rect3} or even rect(4)={rect1,....}
classBackground(){
texture.loadFromFile("wagon.png");
image.setTexture(texture);
image.setPosition(300,250);
rect[0].setSize(sf::Vector2f(230,5));
rect[0].setPosition(image.getPosition());
rect[0].move(0,60);
rect[1].setSize(sf::Vector2f(230,5));
rect[1].setPosition(image.getPosition());
rect[1].move(0,225);
rect[2].setSize(sf::Vector2f(5,170));
rect[2].setPosition(image.getPosition());
rect[2].move(0,60);
rect[3].setSize(sf::Vector2f(5,170));
rect[3].setPosition(image.getPosition());
rect[3].move(225,60);
}
};
//in the main function
classMainCharacter mainCharacter; ///another class which has collision detection
classBackground background;
///in the loop
for(int i = 0; i<=3; i++){
mainCharacter.collision(background.rect[i]); ///colision is a function in the mainCharacter class (detects collision)
}
what am I doing wrong? :(
I tried to defined the rects before vector and then inserting into the vector but it also doesn't work (in such way vector<...> rect = {......}).
Well even if I would not expect to much difference between the two versions, an answer is worth telling anyway as your problem has neither to do with performance nor with sfml at all but is more general.
What you try is to instantiate a class member at its declaration, what is not possible. But what you can do is either one of the following methods:
1) Use the default member initializer with the C++ 11 unified initialization syntax like so (wich may only be syntactic sugar for (2) prior to this: http://en.cppreference.com/w/cpp/language/data_members#Member_initialization):
std::vector<sf::RectangleShape> rect{4}
2) Use the initializer list in the constructor:
classBackground() : rect(4) {...}
3) Or call the resize method in the constructor:
classBackground(){
rect.resize(4);
...
}
The last one might be the worst as it first calls the standard constructor of vector<...> and changes it afterwards.
In the first version, you were successfully creating a vector of 4 elements by using push_back.
In the second version, you never allocate space for your 4 elements, so when you try and assign values to the elements of the vector, that's your crash.
If you really don't want to use push_back you can instead use resize to set the size of the vector.
Here's a simplified version of what you're trying to do
#include <vector>
class classBackground {
std::vector<int> rect;
public:
classBackground() {
rect.resize(4);
rect[0] = 1;
rect[1] = 2;
rect[2] = 3;
rect[3] = 4;
}
};
int main() {
classBackground cb;
// there, it worked.
}
Demo: http://ideone.com/YYq0oA
Alternatively if you have C++11 and your vector is always going to be 4 elements large, which in this case it seems like it might be, you should consider using std::array instead.
#include <array>
class classBackground {
std::array<int, 4> rect;
public:
classBackground() {
rect[0] = 1;
rect[1] = 2;
rect[2] = 3;
rect[3] = 4;
}
};
int main() {
classBackground cb;
// there, it worked.
}
Array works like vector in most ways, you just can't change the size, but it can potentially be more efficient.

2D Vector of Class gets error when accessing function

After converting my 2D array to a 2D vector (due to all the praise I heard about it), my program breaks almost immediately, and after some testing, it appears to happen when the program tries to do a function with a vector element. I have made some simplified source code, which also has the error:
#include <iostream>
#include <vector>
using namespace std;
class Dog
{
private:
int mass, size;
public:
void setMass(int);
void setSize(int);
int getMass();
int getSize();
};
void Dog::setMass(int newMass) {mass = newMass;}
void Dog::setSize(int newSize) {size = newSize;}
int Dog::getMass() {return mass;}
int Dog::getSize() {return size;}
int main()
{
vector <vector<Dog*> > dogs(10, vector<Dog*> (10));
dogs[0][0]->setMass(10);
dogs[0][0]->setSize(5);
return 0;
}
I also have a link to Ideone, so it is easier to test (and where I tested the code) http://ideone.com/e.js/mqVuv3
You have a 2D vector of pointer-to-Dog but are not allocating any Dog objects. When you initialize the 2D vector the pointers are initialized to nullptr. Dereferencing a nullptr is undefined behaviour.
Unless you have a good reason not to, I suggest you just have a 2D vector of Dogs:
vector<vector<Dog>> dogs(10, vector<Dog>(10));
Then you will have 100 default constructed Dogs and you can happily set their mass and size:
dogs[0][0].setMass(10);
dogs[0][0].setSize(5);

Passing a vector to constructor

Iam new in C++ and iam trying to implement classes into my program. I have done similar program in java. But iam struggling to implement classes in c++. I want to pass a vector with strings from main to a class called Search.I can pass a vector either by value or reference. Iam using a vector * which means get vector address.This is what i was told. Iam not sure how i should refer to it. I am sure there are more mistakes in my code. Could please someone help me or explain me how to initialize vector in constructor and how to add a value so I can use the vector in the menthod?? Iam using Visual Studio PRO 2010. Many thanks for replies.
Search.h
// pragma once
#include "std_lib_facilities.h"
#include <vector>
class Search
{
public:
Search();
Search(int dd, int mm, int year,vector<string>* dat);
vector<string> get_result ();
~Search(void);
private:
int d;
int m;
int y;
vector<string> data;
};
Search.cpp
#include "Search.h"
#include <vector>
#include "std_lib_facilities.h"
Search::Search()
:d(1), m(1), y(2000), data(){} //data() is the vector but iam not sure if ihave set the value corectly
Search::Search(int dd, int mm, int year,vector<string>*dat)
:d(dd),m(mm),y(year), data(dat){}//no instance of constructor matches the construcor list -- this is the error iam getting
//iam trying to initiliaze the varibale data of type vector.But i dont know how to do it.
Search::~Search(void)
{
}
vector<string> Search::get_result () {// implementation where i need to use the data stored in a vector
}
//main program
#include "std_lib_facilities.h"
#include <string>
#include <sstream>
#include <stdio.h>
#include "Search.h"
#include <vector>
int main(){
int day, month, year; //iam gonna ask user to input these
day=20;
month=12;
year=2014;
vector<string>flight_info;
ifstream inputFile("flight.txt");
// test file open
if (inputFile) {
string value;
// read the elements in the file into a vector
while ( inputFile >> value ) {
flight_info.push_back(value);//this is the vector i want to pass to class Search
}
}
Search search(day,month,year,flight_info)
//this where i want to create object of Search class but iam gettin error -no instance of constructor matches the `enter code here`construcor list.
}
This defines a vector:
vector<string>flight_info;
This defined a vector member variable:
vector<string> data;
This invoke a constructor by passing the vector to it:
Search search(day,month,year,flight_info)
But this constructor expects a pointer to a vector!
Search(int dd, int mm, int year,vector<string>* dat);
You don't need to pass any of the standard containers around by pointer (and you're probably doing something wrong if you find yourself trying to).
You can rewrite your constructor to be Search(int dd, int mm, int year,vector<string> dat) to resolve your error. You only need to change the prototype of your constructor, because data(dat) will already correctly construct the member vector.

Segfault when pushing to member vector

Here's a relatively small but segfaulting project. I've searched quite a few posts doing similar things and while many seemed to be having the same problem, none solved my problem.
The basic issue is this: I have an object (myGraph) with a member vector, and a few methods. A method inside another class invokes one of myGraph's methods, which in turn invokes another one. Inside that function, a push is made to a vector of ints in myGraph. However, this push results in a segfault.
In a somewhat extreme measure, I've been commenting out large portions of code (on a fresh branch of course) and have reduced my code down to a sparse few items. (other posts seemed to indicate that this kind of thing might be caused by bad code elsewhere) yet I am still getting a segfault.
What follow are the watered-down files, composed of the few things remaining uncommented. I say "watered-down" because a lot of declarations (of now-empty functions and such) have been removed. If you need additional information (for instance, if it's important - somehow - that I'm using a virtual function somewhere... as a radical example) just let me know.
in Dispatcher.h:
class myGraph;
class CDispatcher
{
public:
CDispatcher(void);
~CDispatcher(void);
void ProcessCall(string buf);
myGraph* mymap;
};
in Dispatcher.cpp:
void CDispatcher::ProcessCall(string buf)
{
mymap->getDistance(0,1);
};
in mygraph.cpp:
int myGraph::getDistance(int start, int end) {
Dijkstras(start,end);
// This is just to return something
return 5;
};
vector<int> myGraph::Dijkstras(int startVert,int endVert) {
vertices_i.push_back(2); // This line results in a segfault
cout << "push successful" << endl;
// This is just to return something
vector<int> unvisited;
return unvisited;
};
mygraph.h:
typedef struct edge
{
int endVert;
int weight;
} edge;
typedef struct vertex
{
long dist;
bool visited;
int prev;
vector<edge> edges;
} vertex;
class myGraph
{
public:
myGraph(int initSize);
~myGraph(void);
int getDistance(int start, int end);
vector<int> Dijkstras(int startVert,int endVert);
//vector<vertex> vertices; // The original vector that was segfaulting
vector<int> vertices_i; // Simpler vector, of just ints. Still segfaults
};
The unavoidable conclusion is that the member pointer myGraph* mymap is pointing to garbage; you've apparently neglected to initialize it to point to a myGraph object. You need to create an object for it to refer to in the CDispatcher constructor -- i.e.,
CDispatcher(void) : mymap(new myGraph(1)) {}