I have a structure as
struct Employee
{
char uName [255];
struct Employee * next;
struct Employee * prev;
};
All i want to allocate memory of 100 stucture objects at a time and then use them one by one i making a linked list.If the memory is consumed fully then again i want to allocate 100 object memory
I am doing the allocation as
struct Employee * chunk=new struct Employee[100];
Now when i want to add a new node to a linked list i want to take objects from this already allocated memory.Can somebody tell how to achieve this
Employee * pEmployeeData=NULL;
for(long int i=1;i<=100;i++)
{
pEmployeeData=EmployeePool+i;
pEmployeeData->next=NULL;
pEmployeeData->prev=NULL;
InsertAtEnd(pEmployeeData);
}
where InsertAtEnd inserts the node at the end of the linked list.Please tell how to achieve this
I would strongly suggest that you don't try to reinvent the wheel by writing your own linked list, instead have a look at the C++ standard library which contains ready-made container types available for you to use. (for example std::vector and std::list).
Container types exist in the C++ standard library, and are used for storing collections of data/objects. for example, you could do something along the lines of
#include <iostream>
#include <vector>
#include <string>
struct Employee
{
std::string name;
int id;
};
int main()
{
std::vector<Employee> my_employees;
Employee fred = { "Fred", 1 };
Employee bob = { "Bob", 2 };
my_employees.push_back( fred );
my_employees.push_back( bob );
std::cout << my_employees[0].id << " " << my_employees[0].name << "\n"
<< my_employees[1].id << " " << my_employees[1].name << std::endl;
}
The standard containers are easy to use and to learn (You'll find plenty of internet resources which describe how to use them - and your book should also tell you!); If you're new to C++, then it's highly advisable to start out by figuring out how to use these before attempting to create your own.
You'd override the new and delete operators for your class.
new would have to look at any existing pools and see if there were any free objects, and if there weren't, it would then need to allocate a pool. Then, it would return memory allocated from it.
delete would need to check the pool that the provided object was allocated in. If ANY object is still allocated in it, the pool stays, otherwise, it can be deleted.
Also, since you're using C++, consider using a full blown class (though there is very little difference)
Related
Why do we use a pointer of object when we want to create a new object like this?
employee *Steve = new employee();
In this case, I want to create an object named Steve.
#include <iostream>
#include <string.h>
using namespace std;
class employee{
private:
char name[40];
int salary;
public:
employee(){
strcpy(name, "unnamed");
salary = 0;
}
char *getName(){
return name;
}
};
int main(){
employee *Steve = new employee();
cout<<"Name: "<< Steve->getName();
}
We do not use pointers when we do not need pointers. When we want to create an object we call a constructor to create an object, but we do not use new nor raw pointers.
employee Steve;
std::cout << "Name: " << Steve.getName() << "\n";
If we dynamically allocate the object then we still do not use new or raw poitners, but container or smart pointers.
In bad tutorials and questionable teaching they use pointers a lot. Often that is because they do not actually aim to teach C++, but rather to teach pointers. In modern C++ the use of raw pointers is limited to rare cases.
There would be more to say about the code you wrote, but I'll leave it at that and refer you to The Definitive C++ Book Guide and List.
I'm trying to create a connected graph and to perform certain computations on it. To do that, from each node in this graph, I need to access its neighbors and to access its neighbor's neighbors from its neighbor and so forth. This inevitably creates many (useful) cyclic dependencies.
Below is a simplified example with 3 mutually connected nodes (like the 3 vertices of a triangle), and I'm not sure if this method is a good way to do it, particularly if the clean-up leaves any memory leaks :
#include <iostream>
#include <vector>
class A {
public:
int id;
std::vector<A*> partners;
A(const int &i) : id(i) {
std::cout << id << " created\n";
}
~A() {
std::cout << id << " destroyed\n";
}
};
bool partnerUp(A *a1, A *a2) {
if (!a1 || !a2)
return false;
a1->partners.push_back(a2);
a2->partners.push_back(a1);
std::cout << a1->id << " is now partnered with " << a2->id << "\n";
return true;
}
int main() {
std::vector<A*> vecA;
vecA.push_back(new A(10));
vecA.push_back(new A(20));
vecA.push_back(new A(30));
partnerUp(vecA[0], vecA[1]);
partnerUp(vecA[0], vecA[2]);
partnerUp(vecA[1], vecA[2]);
for (auto& a : vecA) {
delete a;
a = nullptr;
}
vecA.clear();
return 0;
}
I'm also aware that I can use shared_ptr + weak_ptr to complete the task, but smart pointers come with an overhead and I'd love to avoid that whenever possible (I also hate to use .lock() all the time to access the data, but that doesn't really matter). I rewrote the code using smart pointers as follows, and I'd like to know what are the differences between the 2 pieces of code (outputs of the two codes are identical).
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class A {
public:
int id;
vector<weak_ptr<A>> partners;
A(const int &i) : id(i) {
cout << id << " created\n";
}
~A() {
cout << id << " destroyed\n";
}
};
bool partnerUp(shared_ptr<A> a1, shared_ptr<A> a2) {
if (!a1 || !a2)
return false;
a1->partners.push_back(a2);
a2->partners.push_back(a1);
cout << a1->id << " is now partnered with " << a2->id << "\n";
return true;
}
int main() {
vector<shared_ptr<A>> vecA;
vecA.push_back(make_shared<A>(10));
vecA.push_back(make_shared<A>(20));
vecA.push_back(make_shared<A>(30));
partnerUp(vecA[0], vecA[1]);
partnerUp(vecA[0], vecA[2]);
partnerUp(vecA[1], vecA[2]);
return 0;
}
You can prevent memory leaks by using a principle of ownership: At every point, there needs to be an owner who is responsible for freeing the memory.
In the first example, the owner is the main function: It undoes all the allocations.
In the second example, each graph node has shared ownership. Both vecA and the linked nodes share ownership. They are all responsible in the sense that they all call free if necessary.
So in this sense, both versions have a relatively clear ownership. The first version is even using a simpler model. However: The first version has some issues with exception safety. Those are not relevant in this small program, but they will become relevant once this code is embedded into a larger application.
The issues come from transfer of ownership: You perform an allocation via new A. This does not clearly state who the owner is. We then store this into the vector. But the vector itself won't call delete on its elements; it merely call destructors (no-op for a pointer) and deletes its own allocation (the dynamic array/buffer). The main function is the owner, and it frees the allocations only at some point, in the loop at the end. If the main function exits early, for example due to exception, it won't perform its duties as the owner of the allocations - it won't free the memory.
This is where the smart pointers come into play: They clearly state who the owner is, and use RAII to prevent issues with exceptions:
class A {
public:
int id;
vector<A*> partners;
// ...
};
bool partnerUp(A* a1, A* a2) {
// ...
}
int main() {
vector<unique_ptr<A>> vecA;
vecA.push_back(make_unique<A>(10));
vecA.push_back(make_unique<A>(20));
vecA.push_back(make_unique<A>(30));
partnerUp(vecA[0].get(), vecA[1].get());
partnerUp(vecA[0].get(), vecA[2].get());
partnerUp(vecA[1].get(), vecA[2].get());
return 0;
}
The graph can still use raw pointers, since the ownership is now solely the responsibility of the unique_ptr, and those are owned by vecA, and that is owned by main. Main exits, destroys vecA, and this destroys each of its elements, and those destroy the graph nodes.
This is still not ideal, though, because we use one indirection more than necessary. We need to keep the address of the graph nodes stable, since they're being pointed to from the other graph nodes. Hence we should not use vector<A> in main: if we resize that via push_back, this changes the addresses of its elements - the graph nodes - but we might have stored those addresses as graph relations. That is, we can use vector but only as long as we haven't created any links.
We can use deque even after creating links. A deque keeps the addresses of the elements stable during a push_back.
class A {
public:
int id;
vector<A*> partners;
// ...
A(A const&) = delete; // never change the address, since it's important!
// ...
};
bool partnerUp(A* a1, A* a2) {
// ...
}
int main() {
std::deque<A> vecA;
vecA.emplace_back(10);
vecA.emplace_back(20);
vecA.emplace_back(30);
partnerUp(&vecA[0], &vecA[1]);
partnerUp(&vecA[0], &vecA[2]);
partnerUp(&vecA[1], &vecA[2]);
return 0;
}
The actual problem of deletion in a graph is when you don't have a data structure like your vector in main: It is possible to just keep pointers to one or several nodes from which you can reach all other nodes in main. In that case, you need graph traversal algorithms to delete all nodes. This is where it gets more complicated and hence more error prone.
In terms of ownership, here the graph itself would have ownership of its nodes, and main has ownership of just the graph.
int main() {
A* root = new A(10);
partnerUp(root, new A(20));
partnerUp(root, new A(30));
partnerUp(root.partners[0], root.partners[1]);
// now, how to delete all nodes?
return 0;
}
Why would the second approach be recommended?
Because it follows a widespread, simple pattern that reduces the likelyhood of a memory leak. If you always use smart pointers, there'll always be an owner. There's just no opportunity for a bug that drops ownership.
However, with shared pointers, you can form cycles where multiple elements are kept alive because they own each other in a cycle. E.g. A owns B and B owns A.
Therefore, the typical rule-of-thumb recommendations are:
Use a stack object, or if not possible, use a unique_ptr or if not possible, use a shared_ptr.
For multiple elements, use a container<T>, or container<unique_ptr<T>> or container<shared_ptr<T>> in that order.
These are rules of thumb. If you have time to think about it, or some requirements like performance or memory consumption, it can make sense to define a custom ownership model. But then you also need to invest the time to make that safe and test it. So it should really give you a great benefit to be worth all the effort needed to make it safe. I would recommend against assuming that shared_ptr is too slow. This needs to be seen in the context of the application and usually measured. It's just too tricky to get custom ownership concepts right. In one of my examples above, you need to be very careful with resizing the vector, for example.
Introduction
I have two classes I call Node and Point here. Points are objects which hold specific information (which information exactly does not matter I use a simple integer in the example). Nodes are objects which manage several points if they should share the same information. So Node has a list of pointers to all the points it manages (which is fine because Pointremoves its reference from the node if its lifetime ends) and each point has a back reference to the node itself. This creates a circular reference which makes things a bit tricky. I do not use multithreading, so races of any kind are not a concern. Also I am bound to use C++03 (so C++98, basically) and boost 1.53 so there is a limitaion in features I can use.
EDIT:
as it seems to be a bit unclear i wanted to add that this is really a very minimalistic extraction of the actual code. As i wanted to provide a minimal working example i tried my best to extract the functionality from the original program. However be sure that using shared pointers is necessary in the actual program since these resources are shared across several objects with different classes. Also i use shared pointers because they are always optional which means you can check them for NULL and act differently if they are not assigned as can also be seen in the code below.
The problem
I have not yet described the "back reference to the node" any further because this is where the problem begins. So at the moment I settled with this solution:
My Node contains a weak pointer to itself so the ownership can be shared to other points. On adding a point, the node creates a shared pointer from the weak pointer like this
p->node = this->weakThis.lock();
but I do not know if this is just bad practice or contains serious problems which I do not see since the reference to weak_ptr::lock() only states that it creates a new shared object despite its confusing name, or if this is acceptable code.
Other solutions I have thought of
All classes get shared pointers
good: No need to create shared objects from weak ones
bad: The shared object inside the class needed to be explicitely deleted (like with a call of a method for example Node::destroySelfReference() which can easily be forgotten. Otherwise the object could live forever with a reference to itself.
All classes get weak pointers
good: we just need to copy the weak pointer and not share ownership
bad: everytime we wanted to access the node from the point we needed to call lock(). And since the reference in Point is not really used as observer but is used like a shared reference this is obsolete.
Question
What would be the best solution here? And which are the real dangers of them?
Code
/* Using boost 1.53 */
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/weak_ptr.hpp>
using boost::shared_ptr;
using boost::make_shared;
using boost::weak_ptr;
using std::cout;
using std::endl;
/*-------------Classes-----------*/
class Point;
class Node {
private:
std::vector<Point *> points;
weak_ptr<Node> weakThis;
public:
int value;
Node(Point * p, shared_ptr<Node> & sp);
void add(Point * p);
void remove(Point * p);
int getValue() {
return this->value;
}
};
class Point {
private:
int value;
public:
shared_ptr<Node> node;
Point() : value(2) {}
~Point() {
if(this->node != NULL) {
this->node->remove(this);
}
}
int getValue() {
if (this->node == NULL) return this->value;
else {
return this->node->getValue();
}
}
};
/*----------Node definition------------*/
Node::Node(Point * p, shared_ptr<Node> & sp) : value(1) {
sp.reset(this);
this->weakThis = sp;
this->add(p);
}
void Node::add(Point * p) {
this->points.push_back(p); /* simplified without checking if element exists since it is unnecessary for the problem */
p->node = this->weakThis.lock(); /* <- critical part */
}
void Node::remove(Point * p) {
std::vector<Point *>::iterator it = std::find(this->points.begin(), this->points.end(), p);
if (it != this->points.end()) {
Point * pr = *it;
this->points.erase(it);
pr->node.reset();
}
}
/*------------main-----------*/
int main() {
Point p;
cout << "Value of unmanaged p is " << p.getValue() << endl;
shared_ptr<Node> n;
new Node(&p, n); /* This is a bit strange too but other creations will not work */
cout << "Added p to n" << endl;
cout << "Value of managed p is " << p.getValue() << endl;
n->remove(&p);
n.reset();
return 0;
}
I'm trying to access the variable name of the Reservation struct like this hotel[SomeIndex].reservations[AnotherIndex].name but it's not working.
How can I access those variables to fill the structure?
PS: It compiles,but it shows in debugger Segmentation Fault.
struct Reservation{
string name;
};
struct Hotel {
string name;
Reservation *reservations;
};
int main()
{
struct Hotel *hotel;
hotel = new Hotel[20];
hotel->reservations=new Reservation[10];
hotel[9].name="Olympus Plaza";
hotel[9].reservations[5].name="John Doe";
cout<<"Hotel: "<<hotel[9].name<<" Name: "<<hotel[9].reservations[5].name<<endl;
return 0;
}
You do not correctly initialize the reservations. Doing this correctly with raw pointers is hard and error-prone, and absolutely not recommended in C++.
First of all, use an std::vector<Hotel> instead of a raw array Hotel *. Vectors are the normal C++ "array" objects.
You can then replace the raw Reservation * pointer inside the Hotel struct with a std::vector<Reservation> as well.
This makes it much easier to fix the actual error: The missing initialization.
What you did was create 20 hotels, then create 10 reservations for the first hotel! Then you try to access reservations for the 9th hotel, where there is an uninitialized pointer which points to random data. This means the behaviour is undefined: In this case, a segmentation fault is the way that your system shows you that you are accessing data which doesn't belong to you.
You need a loop to create reservations for each of the hotels, or if you just want to create reservations in the 9th hotel, you need to specify its index.
Using std::vector is very simple:
#include <vector>
struct Reservation {
string name;
};
struct Hotel {
string name;
vector<Reservation> reservations;
// if you have no "using namespace std", then it's "std::vector".
};
And then you can just create reservations for the correct hotel:
int main()
{
vector<Hotel> hotel(20);
hotel[9].reservations.resize(10);
hotel[9].name="Olympus Plaza";
hotel[9].reservations[5].name="John Doe";
cout<<"Hotel: "<<hotel[9].name<<" Name: "<<hotel[9].reservations[5].name<<endl;
return 0;
}
hotel->reservations=new Reservation[10]; is equivalent to hotel[0].reservations=new Reservation[10];. You've initialised hotel[0] but none of the other elements of hotel - specifically not hotel[9].
It looks like what you need is to define constructors for Hotel and Reservation that initialise all their members to well-defined values.
And I would strongly suggest you use std::vector rather than raw arrays; arrays are an advanced feature and very easy to go wrong with.
I want to create a generic linked list in C/C++ (without using templates of C++).
I have written following simple program and it works fine as of now -
typedef struct node
{
void *data;
node *next;
}node;
int main()
{
node *head = new node();
int *intdata = new int();
double *doubledata = new double();
char *str = "a";
*doubledata = 44.55;
*intdata = 10;
head->data = intdata;
node *node2 = new node();
node2->data = doubledata;
head->next = node2;
node *node3 = new node();
node3->data = str;
node3->next = NULL;
node2->next = node3;
node *temp = head;
if(temp != NULL)
{
cout<<*(int *)(temp->data)<<"\t";
temp = temp->next;
}
if(temp != NULL)
{
cout<<*(double *)(temp->data)<<"\t";
temp = temp->next;
}
if(temp != NULL)
{
cout<<*(char *)(temp->data)<<"\t";
temp = temp->next;
}
return 0;
}
My question is -
I need to know the data type of the data I am printing in the code above.
For example - first node is int so i wrote -
*(int *)(temp->data)
second is double and so on...
Instead, is there any generic way of simply displaying the data without worrying about the data type?
I know you can achieve this with templates, but what if I have to do this in C only ?
Thanks,
Kedar
The whole point of a generic list is that you can store anything in it. But you have to be realistic... You still need to know what you are putting in it. So if you are going to put mixed types in the list, then you should look at using a Variant pattern. That is, a type that provides multiple types. Here's a simple variant:
typedef struct Variant
{
enum VariantType
{
t_string,
t_int,
t_double
} type;
union VariantData
{
char* strVal;
int intVal;
double doubleVal;
} data;
} Variant;
You can then tell yourself "I'm storing pointers to Variants in my void* list. This is how you would do it in C. I assume when you say "C/C++" you mean that you're trying to write C code but are using a C++ compiler. Don't forget that C and C++ are two different languages that have some overlap. Try not to put them together in one word as if they're one language.
In C, the only way to achieve generics is using a void*, as you are already doing. Unfortunately, this means that there is no easy way to retrieve the type of an element of your linked list. You simply need to know them.
The way of interpreting data in memory is completely different for different data type.
Say a 32 bit memory block has some data. It will show different values when you typecast it as int or float as both are stored with different protocols. When saving some data in memory pointed by variable of type void*, it does not know how to interpret the data in its memory block. So you need to typecast it to specify the type in which you want to read the data.
This is a little bit like sticking all the cutlery in a drawer, but instead of putting knifes in one slot, forks in another slot, and spoons in a third slot, and teaspoons in the little slot in the middle, we just stick them all in wherever they happen to land when chucking them in, and then wondering why when you just stick your hand in and pick something up, you can't know what you are going to get.
The WHOLE POINT of C++ is that it allows you to declare templates and classes that "do things with arbitrary content". Since the above code uses new, it won't compile as C. So there's no point in making it hold an non-descriptive pointer (or even storing the data as a pointer in the first place).
template<typename T> struct node
{
T data;
node<T> *next;
node() : next(0) {};
};
Unfortunately, it still gets messier if you want to store a set of data that is different types within the same list. If you want to do that, you will need something in the node itself that indicates what it is you have stored.
I have done that in lists a few times since I started working (and probably a couple of times before I got a job) with computers in 1985. Many more times, I've done some sort of "I'll store arbitrary data" in a something like a std::map, where a name is connected to some "content". Every time I've used this sort of feature, it's because I'm writing something similar to a programming language (e.g. a configuration script, Basic interpreter, LisP interpreter, etc), using it to store "variables" that can have different types (int, double, string) or similar. I have seen similar things in other places, such as OpenGL has some places where the data returned is different types depending on what you ask for, and the internal storage has to "know" what the type is.
But 99% of all linked lists, binary trees, hash-tables, etc, that I have worked on contain one thing and one thing only. Storing "arbitrary" things in a single list is usually not that useful.
The answer below is targeting at C++ and not C. C++ allows for what you want, just not in the way that you want to do it. The way I would implement your problem would be using the built-in functionality of the virtual keyword.
Here's a stand-alone code sample that prints out different values no matter the actual derived type:
#include <iostream>
#include <list>
class Base
{
public:
virtual void Print() = 0;
};
class Derived1 : public Base
{
public:
virtual void Print()
{
std::cout << 1 << std::endl; // Integer
}
};
class Derived2 : public Base
{
public:
virtual void Print()
{
std::cout << 2.345 << std::endl; // Double
}
};
class Derived3 : public Base
{
public:
virtual void Print()
{
std::cout << "String" << std::endl; // String
}
};
int main(void)
{
// Make a "generic list" by storing pointers to a base interface
std::list<Base*> GenericList;
GenericList.push_back(new Derived1());
GenericList.push_back(new Derived2());
GenericList.push_back(new Derived3());
std::list<Base*>::iterator Iter = GenericList.begin();
while(Iter != GenericList.end())
{
(*Iter)->Print();
++Iter;
}
// Don't forget to delete the pointers allocated with new above. Omitted in example
return 0;
}
Also notice that this way you don't need to implement your own linked list. The standard list works just fine here. However, if you still want to use your own list, instead of storing a void *data;, store a Base *data;. Of course, this could be templated, but then you'd just end up with the standard again.
Read up on polymorphism to learn more.