How to return dynamic structure without pointer? - c++

I have to overload '+' operator for two dynamic containers.
Occurance Occurance::operator +(const Occurance& occ) const {
Occurance* result = new Occurance;
Iterator i1(head);
Iterator i2(occ.head);
while( !(i1.isNULL() && i2.isNULL()) ) {
if(i1.getCount() >= i2.getCount()) {
result->add(i1.getFile());
result->tail->count = i1.getCount();
++i1;
}
else {
result->add(i2.getFile());
result->tail->count = i2.getCount();
++i2;
}
}
return *result;
}
When I do:
Occurance occ = occ1+occ2;
Pointers to the begin of the list are copied correctly and everything works fine but I'm losing reference to result. When occ destructor is called whole list is destroyed, but not the first element of result as I have simply copied it's content instead of reference.
When I change return type to reference the same occurs but during assignment.
Another idea is to not create the 'result' dynamically, so it's automaticly destroyed at the end of function, but then it's calling the destructor which is destroying whole list.
Is there any simple and "proper" way to create such structure and return it without this memory leak? And of course the returned type must be the object or reference as it is expected from '+' operator.
I have figured out a nasty hack involving changing pointer to function in the destructor, but maybe I'm just missing something very simple?
Edit:
Of course class follows the rule of three. Here is assignment:
Occurance& Occurance::operator =(const Occurance& occ) {
destruct();
head = occ.head;
current = occ.current;
tail = occ.tail;
return *this;
}
Occurance::Occurance(const Occurance& occ) {
head = occ.head;
current = occ.current;
tail = occ.tail;
}
Occurance::~Occurance() {
destruct();
}
destruct just destroys the list that starts at 'head'.
The class declaration:
class Occurance {
private:
class Node {
public:
Node* next;
Node* prev;
int count;
const File* file;
Node(const File& a_file, Node* a_prev);
};
Node* head;
Node* tail;
Node* current;
void destruct();
public:
class Iterator {
private:
Node* node;
public:
Iterator();
Iterator(Node* a_node);
void operator ++();
const File& getFile();
int getCount();
bool isNULL();
};
Occurance();
Occurance(const Occurance& occ);
void add(const File& a_file);
Occurance& operator =(const Occurance& occ);
Occurance operator +(const Occurance& occ) const; //dodaje listy zachowujÄ…c sortowanie
Iterator begin() const;
virtual ~Occurance();
};

Your copy constructor and assignment operator are broken. You either need to do a deep copy of your list, or you need to implement some kind of sharing semantics (e.g. reference counting). You appear to have a linked list, and you are simply copying the head and tail pointers. So when you make a copy, and one is destroyed, it destroys the other one's list too.
I assume your default constructor and/or your add function does some dynamic allocation of nodes. Then your copy constructor and assignment operator need to dynamically allocate nodes too, which are completely independent of the nodes of the object which is being copied. If C++11 is available to you, you should also consider implementing a move constructor, and a move assignment operator.
Once those functions are all correct, your operator+ should look something like this:
Occurance Occurance::operator +(const Occurance& occ) const {
Occurance result; // no dynamic allocation
// operate on result
return result;
}

Another idea is to not create the 'result' dynamically, so it's automaticly destroyed at the end of function, but then it's calling the destructor which is destroying whole list.
You should read about copy constructor. Before the returning object's destructor is called, the copy constructor is called that copies the data from that object to the temporary object that will hold the result of occ1+occ2 operation. I assume you have members that point to dynamically allocated data and in this case, when the copy constructor is called, it assigns the pointer to the temp object instead of allocate new memory and copy data. You must code it on your own. I'd advise you to read: http://www.cplusplus.com/articles/y8hv0pDG/
Also note that you should overload operator = in the same manner if you want to perform this assignment
occ = occ1+occ2
edit: Sorry, I can't comment, could you also copy your class declaration?

In C++, the general principle is to return copies on the stack, not objects allocated on the heap. So in this case you would simply do:
Occurance Occurance::operator +(const Occurance& occ) const
{
Occurance result;
// do whatever
return result;
}
and call it:
Occurance occ = occ1+occ2;
The compiler is smart enough to understand not to make a copy but to re-use the object that you're returning into (this is called return-value optimisation or RVO).
If you really need the object to be the exact same object created inside your function for whatever reason, then you can either: return a smart pointer (look up shared_ptr) or use the new C++11 move operator.

Related

"double free or corruption" error in C++

I was doing some sort of infix-to-postfix conversion.
My program works fine but at the end it gives some sort of error!
I guess the error is on the void printQueueContents(Queue typeInfo) method of following class
template <class T>
class Queue{
private:
int front, rear, max;
T *q;
public:
Queue(int size=0){
front = rear = 0;
max = size;
q = new T[size];
}
~Queue(){
delete []q;
}
int enqueue(T);
T dequeue();
T getValueFromIndex(int index){
return q[index];
}
void printQueueContents(Queue typeInfo){
for(int i=rear; i<front;i++){
if(typeInfo.getValueFromIndex(i)) {
cout<<q[i]<<" ";
} else {
cout<<static_cast<char>(q[i])<<" ";
}
}
cout<<"\n";
}
};
which is called as:
q1.printQueueContents(q2);
And declared as:
Queue<int> q1(200);
Queue<int> q2(200); // Holds data type information for q1
I cannot figure out why is this happening? Any suggestions?
EDIT: Thanks to peoples with answers. I finally managed to solve it by changing the method to:
void printQueueContents(Queue& typeInfo)
so that while calling this function the default copy constructor does not make a copy and destructor does not accidently deletes the same memory location twice. Here's a link that has a intuitive explaination. http://www.drdobbs.com/c-made-easier-the-rule-of-three/184401400
While it is true that since you declared a destructor you should declare copy assignment operator and copy constructor(rule of three). You might not want to have them public though.
Calling a function that takes your class by value will invoke the copy constructor. You rely on the compiler generated copy constructor if you don't declare any and it does member to member assignment. In your case, the q* gets copied as is to your second object. When returning from the function, the parameter passed by value goes out of scope and get destructed which will delete q for the first time. When your program exits, the destructor of the original object gets called as well so q is deleted a second time.
In your case, I think the printQueueContents method should take a const &(or ref) to your Queue instead to avoid (possibly) expensive copy of the Queue object. Same could be said for getValueFromIndex that should return a const & or ref to avoid copy. For int this is not a problem but for classes, it could get expensive quickly.
With that being said, you still have to either implemented copy assignment operator and copy constructor or declared them as private.
You must implement copy constructor and copy assignment operator
Queue(const Queue& rop){
// copy rop to this, means allocate local q buffer, and copy contents of rop.q to it
}
Queue& operator=(const Queue& rop){
// update this with rop, means the same as above
return *this;
}
your class must obey rule of three, mostly because your class is using bare pointer to allocated buffer. You could also use shared_ptr for your buffer, it would manage life time of it.

operator= overload for Linked List issues

I'm having issues with my implementation of the overloaded = operator for a linked list. The List class contains a Node* head pointer and a struct Node containing T* data and Node* next, where T is a template typename. I'm having trouble with what is happening at the end of the operator function where the destructor (in this case handled by makeEmpty) is being called twice by the end of the operator, once after iterating through the list and creating a new list of the same nodes and once after the operator function exits.
Here is the makeEmpty implementation:
// Does the work of the Destructor
template <typename T>
void List<T>::makeEmpty() {
cout << endl << endl << "DESTRUCTOR CALLED" << endl << endl;
List<T>::Node* tempPtr = head;
if (head != NULL) {
List<T>::Node* nextPtr = head->next;
for(;;) {
if (tempPtr != NULL) {
delete tempPtr->data;
tempPtr = nextPtr;
if (nextPtr != NULL)
nextPtr = nextPtr->next;
/*tempPtr = head->next;
delete head;
head = tempPtr;*/
}
else break;
}
}
}
Here is the operator= overload implementation:
// Overloaded to be able to assign one list to another
template <typename T>
List<T> List<T>::operator=(const List& listToCopy) {
List<T> listToReturn;
listToReturn.head = NULL;
List<T>::Node* copyPtr = listToCopy.head;
List<T>::Node* thisPtr = head;
if (copyPtr != NULL && thisPtr != NULL) {
for(;;) {
if (copyPtr != NULL) {
T* toInsert = new T(*copyPtr->data);
listToReturn.insert(toInsert);
copyPtr = copyPtr->next;
}
else{cout << endl << listToReturn << endl << endl; return listToReturn;}
}
}
// if right-hand list is NULL, return an empty list
return listToReturn;
}
I've been debugging for a little bit and it seems that the second time the destructor is called, the head of the list being destroyed contains unreadable memory. I'm not even sure why the destructor is being called twice within the operator since the only list that needs to be destroyed is the listToReturn after it has been returned. (maybe my logic is flawed somewhere... I've just been thinking about this for too long)
If you guys need anymore info about the code, I'd be glad to provide. As usual, this is for an assignment, so I'm only asking for tips that may help me get in the right direction. So thanks to everyone for looking and helping!
You asked for pointers and tips, so I'm giving it:
1) Unnecessary dynamic data member
Your List<T>::Node does not need a dynamic member for the underlying data value. It should be constructible from a const T& and if implementing a C++11-compliant move-construction idiom, a T&& as well. And both should initialize the next member to nullptr
2) Copy-constructor for List<T> is mandetory
In accordance with the Rules of Three, Four, or Five, your class has dynamic members, and as such must properly manage them in a copy-construction and assignment operator action (or hide said implementations, but clearly that isn't an option for you, as it is part of your assignment).
3) Utilize the class copy-constructor for the assignment operator overload
Overloading an assignment operator where dynamic allocations are involved (and they are here, as your linked list of Node mandates it) should ideally utilize the copy-constructor and the copy/swap idiom for lifetime management. This has a number of benefits, the two most important being potentially eliding the copy-operation by an optimizing compiler, and exception safety that maintains objects in their original state.
4) The List<T>::operator = override should return a reference to the current object
The current object being assigned-to (the left side of the operator) should be a by-reference return result. It should be the object that is modified. This is part and parcel with the standard implementation for such an operator. You return a copy, but the original object remains untouched, thereby utterly defeating the purpose of the assignment operator (i.e. the lvalue side isn't actually modified in your implementation at all)
Each of these is addressed in detail below:
Unnecessary dynamic data member
As it is not posted, I must be somewhat soothsaying in what List looks like. I imagine something like this:
template<class T>
class List
{
private:
struct Node
{
T* data;
Node* next;
};
Node *head;
// other members and decls...
};
With this your insertion and copy operations are having to take significant advantages to manage dynamic allocations of T objects where they shouldn't need to. List<T> should certainly own a chain of Node; but Node should own the actual T object, and be responsible for managing it therein; not List<T>. Consider this instead:
template<class T>
class List
{
private:
struct Node
{
T data;
Node* next;
Node(const T& arg)
: data(arg), next()
{}
Node(const Node& arg)
: data(arg.data), next()
{}
private:
// should never be called, and therefore hidden. A
// C++11 compliant toolchain can use the `delete` declarator.
Node& operator =(const Node&);
};
Node *head;
// other members and decls...
};
Now when a new node is needed to hold a T object (such as in an insertion operation) the following can be done:
template<typename T>
void List<T>::someFunction(const T& obj)
{
Node *p = new Node(obj);
// ...use p somewhere...
}
Copy-constructor for List<T> is mandetory
Your linked list, by its very nature, manages a dynamic chain. Therefore this class must implement copy-construction and assignment operations, the latter being part of your assignment and the reason you posted your question. Duplicating a linked list is fairly straight-forward, but some, for whatever reason, make it harder than it seems. The following is one of my preferred ways of doing it:
template<typename T>
List<T>::List(const List<T>& arg)
: head()
{
Node **dst = &head;
const Node* src = arg.head;
while (src)
{
*dst = new Node(*src); // invoke Node copy-construction
dst = &(*dst)->next; // move target to new node's next pointer
src = src->next; // advance source
}
}
This uses a simple technique of a pointer-to-pointer to hold the address of the pointer being populated with the next new node. Initially it holds the address of our head pointer. With each new node added it is advanced to hold the address of the newly added node's next member. Since Node(const Node&) already sets next to nullptr (see prior section) our list is always terminated properly.
Utilize the class copy-constructor for the assignment operator overload
The List<T>::operator = override should return a reference to the current object
Once we have a solid copy constructor, we can use it for overriding our assignment operator. This is done in a not-so-apparent way, but I'll explain after the code:
template<typename T>
List<T>& List<T>::operator=(List<T> byval)
{
std::swap(head, byval.head); // we get his list; he gets ours
return *this;
}
I'm sure you're looking at this and thinking, "Huh??". It deserves some explanation. Look carefully at the parameter byval being passed in, and consider why I named it as I did. It is not a traditional const reference you're likely used to seeing. It is value copy of the right-hand-side of the assignment expression. Thus, to create it the compiler will generate a new List<T>, invoking the copy-constructor to do so. The result of that copy is the temporary object byval we have as our parameter. All we do is exchange head pointers. Think about what that does. By exchanging head pointers we take his list and he takes ours. But his was a copy of the original right-side of the assignment expression, and ours, well, we want it deleted. And that is exactly what will happen when the destructor for byval is fired once this function is finished.
In short it makes code like this:
List<int> lst1, lst2;
lst1.insert(1);
lst2.insert(2);
lst1 = lst2; // <== this line
execute our function on the marked line. That function will make a copy of lst2, passing it into the assignment operator where lst1 will exchange head pointers with the temporary copy. The result will be lst1's old node will be cleaned up by the destructor of byval, and the new node list is properly in place.
There are a number of reasons to do this. First, it makes your assignment operator exception-safe. If an exception is tossed (usually a memory allocation exception, but it doesn't matter) no memory is leaked, and the original object lst1 remains in its original state. Second, the compiler can elide this away entirely if it chooses and the conditions are correct.
Anyway, these are some ideas and some points of bugs in your implementation. I hope you find them useful.

Deep copy into block of c-array on heap

Consider for example a template container class that holds a buffer that is allocated on the heap:
T *_buffer = new T[SIZE]
Just a simple pointer to c array of type T.
This class is templated. However I am having issues with performing a deep copy of an object into my buffer.
In my unit test, i set up a test class:
class test
{
public:
int* _ptrInt;
test() {_ptrInt = nullptr;}
test(const int i)
{
_ptrInt = new int;
*_ptrInt = i;
}
test(const test& other)
{
_ptrInt = new int;
*_ptrInt = *other._ptrInt;
}
~test()
{
delete _ptrInt;
}
};
on my container I call set, passing a temporary as the data:
container.set(0, test(5));
// destructor called on copy immediately after statement, invalidating deep copy in buffer
void set (const int& index, const T& data)
{
int i = realign(index);
T copy = data;
_buffer[i==SIZE?i-1:i] = copy; // ternary statement and index work
}
however, _buffer takes copy as a reference, the moment copy goes out of scope, it deletes the same pointer that is held in the _buffer. I am trying to force the _buffer to assign by value. But I have had no luck.
memcpy still copies the pointers to point to the same address
test copy constructor is correctly called
move semantics would require class to have move constructor
std::vector somehow implements this to copy correctly, whether its T/T*, heap/stack, with/without move constructor, so I know it must be possible
Is there a way I can assign by value to the _buffer on the heap?
You are "assigning by value." However, your test class doesn't implement the assignment operator operator=, so the assignment invokes the compiler-generated default assignment operator which simply copies member-by-member. Hence the problems with shallow assignment.
Also, your copy constructor will explode if other._ptrInt is nullptr.

Destructor deletes copy in function returning dynamic structure

Ok everyone, noob question.
So I have a template class implementing a singly linked list. A function in a class in my program returns one of these lists.
psList<int> psObj::getList() const {
return List;
}
So what is happening is on the call to return List the copy constructor kicks in which does its job nicely and creates a copy of the list. However then the function finishes and goes out of scope and calls the Destructor! All of a sudden the returned linked list gets deleted, as this is what my destructor does, deletes a list and deletes it well.
I understand I could just make the return type a pointer to the head of the copied list and all would be well and good, but the trouble is I would still not be able to create a function returning a copy of a dynamic structure, even if I wanted to, and I do want to.
I was asked for more code.
Here is the copy constructor, which obviously does a deep copy
template<class psClass>
psList<psClass>::psList(const psList &original) {
head = NULL;
if(original.head != NULL) {
psNode<psClass>* iterator = original.head;
while(iterator != NULL) {
pushback(iterator->data);
iterator = iterator->next;
}
}
}
Here is the destructor
template<class psClass>
psList<psClass>::~psList() {
erase();
}
Here is the erase function the destructor calls.
template<class psClass>
void psList<psClass>::erase() {
psNode<psClass>* iterator = head;
psNode<psClass>* buff;
while(iterator != NULL) {
buff = iterator->next;
delete iterator;
iterator = buff;
}
}
So yes I am doing deep copies and deep destructs. The problem is not the depth. The problem is thus. In the original function a deep copy is made and returned. The function goes out of scope and the deep destructor is called on the copy. No more copy.
To better explain here is what it looks like in the debugger
The original list before the getlist function call.
head 0x616080
data 2
next 0x616060
data 12
next 0x0
Here is the List of "return List" once inside the getList function
head 0x616080
data 2
next 0x616060
data 12
next 0x0
Same thing.
Here are the lists "original" and "this" at the end of the copy constructor.
"this"
head 0x63c900
data 2
next 0x63a940
data 12
next 0x0
"original"
head 0x616080
data 2
next 0x616060
data 12
next 0x0
Everything looks great doesn't it.
Now we are back in the getList function and about to step into the final bracket.
psList<int> psObj::getList() const {
return List;
} // This bracket
The list List back in this function is what you would expect it to be
head 0x616080
data 2
next 0x616060
data 12
next 0x0
And now that we step into the final bracket the destructor is called where there is
/*
* No idea what the in chrg thing is or why the debugger is telling me it was
* optimized out but I mentioned it here cause maybe it has something to do with my
* problem
*/
this 0x7ffffffe650
__in_chrg value optimized out
// Look familiar? well it should cause it is the head of the list I returned.
head 0x63c900
data 2
next 0x63a940
data 12
next 0x0
Then bam! The list I just copied and returned gets deleted by the destructor cause it goes out of scope.
To reiterate my original question after that detour. How do I get a dynamic structure to be returned by a function using a deep copy, without having the destructor destroy the said copy.
More code on request
// Simple single link node with default constructor initializing the link to NULL.
template <class psClass>
struct psNode {
psClass data;
psNode<psClass>* next;
psNode() {
next = NULL;
}
};
and the push back function
template<class psClass>
void psList<psClass>::pushback(psClass object) {
psNode<psClass>* ptr = new psNode<psClass>;
ptr->data = object;
if(head == NULL)
head = ptr;
else {
//Have to find the tail now
psNode<psClass>* tail;
psNode<psClass>* iterator = head;
while(iterator != NULL) {
tail = iterator;
iterator = iterator->next;
}
tail->next = ptr;
}
}
And yes I know keeping track of tail would be easier.
Here is the psList class definition:
template <class psClass>
class psList {
public:
psList();
~psList();
psList(const psList &original);
psList(psNode<psClass>* _head);
void erase();
void pushfront(psClass object);
void pushback(psClass object);
bool isEmpty() const;
psNode<psClass>* front() const;
private:
psNode<psClass>* head;
};
No overloaded assignment operator yet. I plan to add it in after I jump over this hurdle.
It would appear that psList's copy constructor makes a shallow copy instead of a deep one. In general, if you manage resources in a class, then you need non-trivial copy constructor, assignment operator and destructor (the "big three"). Please show us the code of psList.
What you are currently doing is effectively as follows:
psList<int> psObj::getList() const { return psList<int>(List); }
This creates a copy of the member List and copies it across to the frame where getList was called. The way that it is copied across depends upon how you call it. If you construct a new psList object from this data, as in
psList<int> newList = obj.getList(); // same as psList<int> newList(obj.getList());
the copy constructor is used. Often the two copies are reduced to a single copy by RVO.
Alternatively, if you are copying to an existing object, as in
psList<int> newList;
newList = obj.getList();
the original object's state is replaced with the data from the returned result, via the assignment operator. If you don't declare one of your own, the compiler will define a public assingment operator for you. But this is simply going to be a copy of each member of your object. That is:
psList & psList::operator=(const psList& src) {
head = src.head;
}
so in the calling code what happens is as follows:
psList<int> newList; // psList default constructor called
newList = obj.getList(); // 1) obj.List copied via copy constructor within getList
// 2) copy of obj.List copy-assigned to newList (simple copy of head pointer)
// 3) copy of obj.List destructed
// newList now has head pointing to destroyed data
which in your case is not what you want, and what you should have done was made sure the copy assignment genuinely peformed the intended deep copy (see copy-and-swap for a method to do so via the copy constructor you've already implemented).
Hence the rule of three: if you need to define your own implementation of any one of the destructor, copy constructor and copy assignment, then you need to define them all (or at least declare the copy assignment and copy ctor private to render your class uncopyable).
As an aside, why not return a reference:
const psList<int> & psObj::getList() const { return List; }
and make the calling function decide whether to make a copy?
psList<int> localList(localPsObj.getList());

Get a copy of "this" (current instance) in C++

I want to have a copy of the currently running instance.
When i change a value in the copy, original object is also affected. The copy acts as an instance.
How to avoid this? I need to create an independent copy of the calling object.
Set operator+(Set s){
Set temp = *this;
for(int i=0; s.elements[i] != '\0'; i++){
temp(s.elements[i]);
}
temp.elements[0] = 'X'; // <- this affects calling object also :(
return temp;
}
The problem is that Set temp = *this; makes a shallow copy, not a deep copy. You will have to modify the copy constructor and assignment operators for the Set class so that they make copies of all the member/contained objects.
E.g:
class Set
{
public:
Set()
{
elements = new SomeOtherObject[12];
// Could make elements a std::vector<SomeOtherObject>, instead
}
Set(const Set& other)
{
AssignFrom(other);
}
Set& operator=(const Set& other)
{
AssignFrom(other);
return *this;
}
private:
void AssignFrom(const Set& other)
{
// Make copies of entire array here, as deep as you need to.
// You could simply do a top-level deep copy, if you control all the
// other objects, and make them do top-level deep copies, as well
}
SomeOtherObject* elements;
};
Not that your function already makes two copies, since it takes its argument and returns its result per copy:
Set operator+(Set s);
So you wouldn't have to copy s, because it's already copied. I suppose this is involuntarily, so you might want to read about how to pass objects to functions and how to return objects from function in C++.
The problem you're reporting, though, hints at your copy constructor not working properly. Did you implement the copy constructor or are you using the compiler-supplied one?
This probably depends on how Set is implemented. If the assignment operator and the copy constructor haven't been overloaded to do a deep copy(including elements) then it won't work as expected.
Have you implemented a copy constructor for your class?
Default copy constructor will copy any pointer in your class, but not the content you are pointing to. You need to create a copy constructor or overload the '=' operator.
I would avoid a char pointer completely and use std::string instead. This way you dont even need a copy constructor and an assigment operator because the compiler generated once will do just fine. (because 'elements' of the 'Set' class is copy-constructible and has an assignment operator)
Here is my solution:
#include <iostream>
#include <string>
class Set{
std::string elements;
public:
Set() {
elements = "";
}
explicit Set(char* _elements) {
if (_elements)
elements = _elements;
}
Set operator+(const Set& s){
Set temp(*this);
temp.elements += s.elements;
return temp;
}
};
Btw. I added a constructor from char* so that 'elements' can somehow be initialized from outside. Not sure if this is what you wanted.
Ok. I went through rule of three and did the following changes... Can you point out what's wrong with this?
#include<iostream>
#include<cstring>
using namespace std;
class Set{
char *elements;
public:
Set() {
elements = new char('\0');
index = -1;
}
Set(const Set& cpy){
*this = cpy;
}
Set operator+(Set s){
Set temp = *this; // IMPORTANT! copy constructor of Set is called, "this" is passed as argument
// * = current OBJECT, else returns ADDRESS of current object
for(int i=0; s.elements[i] != '\0'; i++){
temp(s.elements[i]);
}
return temp;
}
Set& operator=(Set s){
delete [] elements;
elements = new char[strlen(s.elements) + 1];
strcpy(elements, s.elements); //overrides element of "this"
return *this;
}
};