Allocating space for List inside structure - c++

I have a structure as follows:
struct Vertex{
list<int> q;
};
I created an array of size 10 as follows:
Vertex *ver = (Vertex*) malloc(10 * sizeof(Vertex));
Now I wish to insert in the list. I am having a hard time figuring out why is it giving a segmentation fault:
ver[1].q.push_back(10);
Can someone please explain what's wrong here?

mallocjust allocates memory, it doesn't construct any objects in that memory.
You could instead try
Vertex* ver = new Vertex[10];
which does initialize the Vertex structs and its list members.
An even easier way to create 10 Vertex objects is
std::vector<Vertex> ver(10);
This also saves you from the trouble of having to delete[] the objects later.

The constructor for your list q was never called. Either you use the new operator (Vertex* ver = new Vertex[10];) or you use std::vector<Vertex> instead of Vertex*
#include <list>
#include <vector>
std::vector< std::list<int> > q(10);
if you need an array of vertices with 3 scalars of type int you should use this:
#include <array>
#include <vector>
std::vector< std::array<int,3> > q(10);

Related

How to access the struct elements in a array of vectors of struct?

I am new to vectors, but they seem fairly straight forward. I am working off of a profs code and she is allocating an array of vectors[n]. I would like to be able to allocate the elements in the struct on each element in the array.
The struct is called edge
struct edge {
int vertex1;
int vertex2;
int weight;
};
Adj = new vector<edge>[n];
Now I want to be able to allocate vertex1, 2 and weight to each vector for each element of the array. I can't find the right syntax for this.
something along the lines of:
Adj[1].vertex1 = 11;
Adj[1].vertex2 = 20;
Adj[1].weight = 40;
however also specifying their location in the array.
Thanks!!
If you want a new element to be inserted into the vector, you need to use push_back:
std::vector<edge> Adj;
Adj.push_back(Edge{11, 20, 40});
Either that, or you can pre-allocate a given number of elements (by passing the ctor the number of elements).
Note that C++ vectors are 0-indexed in the std library.

Problem with my dynamic array - Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

I have a problem when I'm doing my debugging: Xcode gives:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
I think it's a problem with my dynamic array...
My assignment is to calculate the perimeter of a polygon with points.
So, my program receives points (x and y) to fill an array of Points, then I made another array, distance, which I fill with all the distances, and then I can calculate the perimeter.
I don't know if it's very clear but I'm a beginner in C++.
#include <iostream>
#include "Point.h"
#include "Polygone.h"
using namespace std;
int main() {
int numberSide;
int x,y;
Point* array = nullptr;
Polygone myPolygone;
cout<<"enter number of sides:"<<endl;
cin>>numberSide;
float* distance=new float[numberSide];
cout<<"enter points:"<<endl;
for (int i=0; i<numberSide; i++) {
cin>>x>>y;
Point p(x,y);
array[i]=p;
}
for (int i=0; i<numberSide-1; i++) {
distance[i]=array[i].distance(array[i+1]);
}
distance[numberSide]=array[0].distance(array[numberSide]);
myPolygone.perimeter(distance);
delete [] distance;
return 0;
}
You never actually allocate any space for the array variable - you are only declaring it and assigning it a nullptr value. Thus, when you later try executing the array[i]=p; you are trying to dereference a null pointer, which causes your EXC_BAD_ACCESS error.
To fix this, you need to allocate the array, once you know what size it is (i.e. how many sides your polygon has). You should do this in the same way as you allocate the distance array:
cin>>numberSide;
float* distance=new float[numberSide];
Point* array = new Point[numberSide]; // And you should delete the earlier "Point* array = nullptr;` line
Of course, you also need to free the memory when you have finished with it:
delete [] distance;
delete [] array;
return 0;
However, as you are using C++, a far better way than using raw pointers and the new operator is to use the Standard Template Library's std::vector container, which takes care of all allocating and freeing operations internally. Here are the relevant 'replacement' lines:
#include <vector> // This header defines the `std::vector` container
//...
cin>>numberSide;
std::vector<float> distance(numberSide);
std::vector<Point> array(numberSide);
Then you don't need the delete[] lines, as the vectors' memory will be released automatically when the vectors go 'out of scope'. Also, you don't need to really change any of your other code, as the std::vector class has a [] operator, which works as you would want it to.

Copy an Eigen vector to a C array?

How do I copy an Eigen vector mesh to a C array r?
double *r;
typedef Eigen::VectorXd RealVector;
Eigen::Map<RealVector>(r, 1, mesh.cols()) = mesh;
gives an assert from Eigen
DenseBase::resize() does not actually allow to resize.
The same message comes from either
Eigen::Map<RealVector>(r, mesh.cols()) = mesh;
or
Eigen::Map<RealVector>(r, mesh.cols(), 1) = mesh;
I need the values to be copied, not just mapped.
Since you did not clarify, I'm speculating three possible errors you could have made:
Either your mesh is actually a VectorXd, but then it will always have exactly one column, but potentially multiple rows, i.e., you need to write:
Eigen::VectorXd::Map(r, mesh.rows()) = mesh;
Or your mesh is a RowVectorXd (i.e., having one row and multiple columns). Then you need to write:
Eigen::RowVectorXd::Map(r, mesh.cols()) = mesh;
If mesh actually is a matrix, you need to decide how to map it to linear memory (i.e. row-major or column-major). This is also possible with Map:
Eigen::MatrixXd::Map(r, mesh.rows(), mesh.cols()) = mesh;
You don't have to copy anything actually. You can access the raw data using the .data() member function.
#include <Eigen/Core>
int main()
{
Eigen::VectorXd mesh = Eigen::VectorXd::Random(10);
double * r = mesh.data();
r[5] = 0; // writes to mesh directly
assert(mesh(5) == 0);
}
If you want to copy the data to the pointer, you have to allocate memory, perform the copy and deallocate after use.
#include <algorithm>
#include <Eigen/Core>
int main()
{
Eigen::VectorXd mesh = Eigen::VectorXd::Random(10);
double * r = new double[mesh.size()];
std::copy(mesh.data(), mesh.data() + mesh.size(), r);
assert(r[5] == mesh(5));
delete[] r;
}

nested unique_ptr and stl containers

I have recently read about RAII and have begun using it. I am trying to define graph as adjacency list and allocate the entire DS on heap using unique_ptr. I know that I can define them as stack objects, but I am trying to use unique_ptr's to get used to them.
I am doing the following
unique_ptr to vector --
|-->(unique_ptr)list<edge>
|-->(unique_ptr)list<edge>
|-->(unique_ptr)list<edge>
|-->(unique_ptr)list<edge>
Code:
#include<memory>
#include<vector>
#include<list>
using namespace std;
struct edge {
int vertex;
int weight;
};
int vertices = 10;
unique_ptr<vector<unique_ptr<list<struct edge > > > >
adj_list(new vector<list<struct edge> >(10)); // THIS COMPILES
unique_ptr<vector<unique_ptr<list<struct edge > > > >
adj_list(new vector<list<struct edge> >(10, new list<edge>())); //THIS GIVES COMPILATION ERROR
Can anyone help me correct this?
EDIT:
I have doubt regarding vector being RAII classes.
if I do the following
vector<int> *v;
v = new vector<int> (10);
Do I have to delete the variable v. Or will it automatically free the memory on heap, when it goes out of scope ?
EDIT:
using pointer to vector makes the user responsible for memory management.
Your unique_ptrs are unnecessary. Just use the objects themselves:
vector<list<edge>> adj_list;
RAII does not imply smart pointers, it's the other way around. C++ accomodated RAII long before smart pointers.
Look at vector's constructors here. None of them accepts a pointer to the element. So either use vector<list<struct edge>*> or change the call to this:
list<struct edge> emptyList;
... (new vector<list<struct edge> >(10, emptyList));

Graphs using Adjacency List in c++

I am trying to implement a graph in C++. I am representing a node in graph using a structure which contains two variables - a) an integer to contain some information about the node. b) a list to contain index of other vertex which are connected to it. Following is the code.
// Graphs using adjacency list
#include <iostream>
#include <list>
#include <cstdlib>
using namespace std;
// structure to represent a vertex(node) in a graph
typedef struct vertex{
int info;
list<int> adj; // adjacency list of edges contains the indexes to vertex
} *vPtr;
int main(){
vPtr node = (vPtr)malloc(sizeof(struct vertex));
node->info = 34; // some arbitrary value
(node->adj).push_back(2); // trying to insert a value in the list
return 0;
}
The code is compiling fine but I am getting a run time error while I am pushing back an element in the list. Is there any problem in my structure. I am using code blocks and GNU GCC, C++ 98 compiler to compile my code.
malloc is a C function - it shouldn't be used with C++ objects, which is very well explained here (short answer: in C++, when you are not dealing with POD types, std::list in your case, you must call the object's constructor to have the actual object ready for use, and malloc() does not do that).
You should used new instead. While malloc only allocates a block of memory of size vertex, new does that and also initializes std::list aswell by calling it's constructor (interesting to point out that when you call delete(), you are calling your object's desctructor aswell).
Here is a piece of code that works for your case, although I suggest you to start using more C++ features within C++ projects:
#include <iostream>
#include <list>
#include <cstdlib>
#include <new>
using namespace std;
// structure to represent a vertex(node) in a graph
typedef struct vertex{
int info;
list<int> adj; // adjacency list of edges contains the indexes to vertex
} *vPtr;
int main(){
cout << "allocating memory for our vertex struct... \n";
vPtr node = new vertex();
node->info = 34; // some arbitrary value
(node->adj).push_back(2); // trying to insert a value in the list
cout << "cleaning allocated memory... \n";
delete(node);
return 0;
}
Couple of things.
Because you are using malloc no constructor is ever called, and as
such the non primitive member adj is never constructed and is
NULL.
You are leaking memory since you never free/delete any of your dynamically allocated memory.
If you are using C++ why are you using malloc instead of new and delete?
You don't have to say struct vertex in the sizeof for C++.
To fix it you could do:
vPtr node = new struct vertex(); // also change to delete instead of free
or
// use current malloc line, change adj to be a pointer to a list and new it
// but this will cause additional problems for you since you really need to use a constructor for STL::list
node->adj = new list<int>;
Bottom line you really shouldn't be using malloc here.
This is UpAndAdam's answer, written completely.
// Graphs using adjacency list
//
#include <iostream>
#include <list>
#include <cstdlib>
using namespace std;
// structure to represent a vertex(node) in a graph
typedef struct vertex{
int info;
list<int> *adj; // adjacency list of edges contains the indexes to vertex
} *vPtr;
int main(){
vPtr node = (vPtr)malloc(sizeof(struct vertex));
node->adj = new list<int>;
node->info = 34; // some arbitrary value
(node->adj)->push_back(2); // trying to insert a value in the list
return 0;
}