ostream& operator<<(ostream& out, const hashmap& h)
{
const char *getSymbol = NULL;
h.hashTable->displayHeaders(out);
for ( int hashIndex = 0; hashIndex < maxSize; hashIndex++ )
{
getSymbol = h.hashTable[hashIndex].getSymbol();
if ( getSymbol )
{
out << h.hashTable[hashIndex];
}
}
return out;
}
If I read the code right as the formatting is somewhat off, the problem is most likely that your stock copy constructor does a shallow copy whereas the assignment operator for the same class makes a deep copy. From reading the rest of the code, I assume you meant to make a deep copy instead of just duplicating the m_name and m_symbol pointers.
I'd also strongly suggest that you use std::string instead of raw char pointers - doing that in the first place would have avoided the issues I describe above. It would've also allowed you to use the compiler generate copy constructor, assignment operator and destructor. Less code is good.
Something went wrong with the formatting when you posted your code, so I had to move it to an external editor to read.
The problem is not a memory leak - that would be memory that you failed to reclaim. This is quite the opposite issue. Here, you are trying to reclaim memory that was already freed.
I would bet anything that the failing delete call in the destructor is occuring on an object that was either copied or populated using either the copy constructor or the second overloaded assignment operator. You are performing a shallow copy in those places, resulting in two stock objects referencing exactly the same memory for their mname and msymbol members. Whichever one of the two (or more if you copied many times) is destroyed first will have no problems. Whichever one is destroyed second will fail.
I also make the following observation: your constructor carefully checks symbol and name to see if they actually reference any data. Only then do you proceed to use their values. If they are null, then you assign a value of null to the corresponding members. The first overloaded assignment operator, on the other hand, is copying an instance of stock that for all you know could have null mname or msymbol members. You should treat those values with the same care you did in the constructor and test them before using.
The problem is here:
stock& stock::operator=(stock const * const s)
Look at the logic of this operator and the other assignment operator you declared: you copy m_symbol and m_name differently!
You would be better off defining the assignment operator only once:
stock& stock::operator=(stock const * const s)
{
return this->operator=(*s);
}
Or the other way around if you prefer, but remember that the implementation of this one is off.
Related
Copy ctor basically creates an object using a previously created object.
But what if we just create an object and then use '=' for element by element assignment. This even works if object is created dynamically. So what can the copy constructor do that the assignment operator cannot?
There are a number of good reasons to use copy constructor rather than default constructing an empty object and than assigning the new object to some already existing object.
Reason one. Const-correctness
First, let's play a devil advocate and consider the case when it doesn't matter:
struct X {
int i;
};
X x;
x.i = 10;
X y;
y = x; // Option 1
X y(x) // Option 2
In the example above, there is really no difference between option 1 and option 2, other than better readabilty and code reasoning. But, what if we would like to make our y object a const object - because we don't want it to change over it's lifetime? Than option 1 would not be valid:
const X y;
y = x; // Compilation error!
So, even on the simplest example, we can tell that even for very simple types, differentiating between assignment and copy-construction is very important for const-correctness. (There could be other examples for the same point).
Reason 2. Code efficiency
Next comes performance implications. Let's consider a very broken and incorrect implementation of string class (illustration only, has no place in life other than that):
struct VeryBrokenString {
char* buffer;
VeryBrokenString() buffer(new char[1]) { strcpy(buffer, ""); }
~VeryBrokenString() { delete[] buffer; }
VeryBrokerString& operator= (const VeryBrokenString& rhs) {
delete[] buffer;
buffer = new [strlen(rhs.buffer) + 1];
strcpy(buffer, rhs.buffer);
return *this;
}
VeryBrokenString(const VeryBrokenString& rhs) {
buffer = new [strlen(rhs.buffer) + 1];
strcpy(buffer, rhs.buffer);
}
};
VeryBrokenString one; // init it somehow :)
VeryBrokenString two;
two = one; // Option 1
VeryBrokenString two(one); //Option 2
In the example above, option 1 leads to duplication of efforts - the buffer is first allocated, and than deallocated, only to be allocated again. In option 2 the buffer is allocated only once. So, second point: copy-constructors help to generate more efficient code.
Reason 3. Correctness
Now, let's consider above broken string. While it is wrong on many levels, one particularly bad piece of code is it's assignment operator. It deletes original buffer, and than allocates a new one, copying data from rhs. Two major issues are that if rhs is the same as this, there will be nothing to copy from after deletion. And the second problem is that if for any reason new allocation throws an exception (run out of memory, for example), we would already loose the the original buffer. While the first problem can be addressed with a check for self-assignment (if (&rhs == this) return *this;) the second could not be easily addressed in a straightforward way. One can read about how to write assignment operators in different articles, but agreed approach would be (for this class) somewhere along following lines:
// Rest of BrokenString remains the same
NotSoBrokenString& operator= (const NotSoBrokenString& rhs) {
NotSoBrokenString temp(rhs);
char* const buf = buffer;
buffer = temp.buffer;
temp.buffer = buf;
}
This is much better, since all the allocation is within temp constructor. If it fails - throws an exception - the original buffer remains valid and usable. (It also addresses the problem of self-assignment - no harm would be done when this is the same as rhs, albeit of slight inefficiency).
So, point number three - assignment operators are often done in terms of copy constructors!
Now this answer is becoming quite big, so I won't have an example for this, but often the semantics of the class allows it to be copy-constructed, but not assigned.
Conclusion
The benefits of copy-constructors used over assignment operators include const-correctness, efficiency, code correctness and support for non-trivial semantics.
I'm getting a segmentation fault which I believe is caused by the copy constructor. However, I can't find an example like this one anywhere online. I've read about shallow copy and deep copy but I'm not sure which category this copy would fall under. Anyone know?
MyObject::MyObject{
lots of things including const and structs, but no pointers
}
MyObject::MyObject( const MyObject& oCopy){
*this = oCopy;//is this deep or shallow?
}
const MyObject& MyObject::operator=(const MyObject& oRhs){
if( this != oRhs ){
members = oRhs.members;
.....//there is a lot of members
}
return *this;
}
MyObject::~MyObject(){
//there is nothing here
}
Code:
const MyObject * mpoOriginal;//this gets initialized in the constructor
int Main(){
mpoOriginal = new MyObject();
return DoSomething();
}
bool DoSomething(){
MyObject *poCopied = new MyObject(*mpoOriginal);//the copy
//lots of stuff going on
delete poCopied;//this causes the crash - can't step into using GDB
return true;
}
EDIT: Added operator= and constructor
SOLVED: Barking up the wrong tree, it ended up being a function calling delete twice on the same object
It is generally a bad idea to use the assignment operator like this in the copy constructor. This will default-construct all the members and then assign over them. It is much better to either just rely on the implicitly-generated copy constructor, or use the member initializer list to copy those members that need copying, and apply the appropriate initialization to the others.
Without details of the class members, it is hard to judge what is causing your segfault.
According to your code you're not creating the original object... you're just creating a pointer like this:
const MyObject * mpoOriginal;
So the copy is using bad data into the created new object...
Wow....
MyObject::MyObject( const MyObject& oCopy)
{
*this = oCopy;//is this deep or shallow?
}
It is neither. It is a call to the assignment operator.
Since you have not finished the construction of the object this is probably ill-advised (though perfectly valid). It is more traditional to define the assignment operator in terms of the copy constructor though (see copy and swap idium).
const MyObject& MyObject::operator=(const MyObject& oRhs)
{
if( this != oRhs ){
members = oRhs.members;
.....//there is a lot of members
}
return *this;
}
Basically fine, though normally the result of assignment is not cont.
But if you do it this way you need to divide up your processing a bit to make it exception safe. It should look more like this:
const MyObject& MyObject::operator=(const MyObject& oRhs)
{
if( this == oRhs )
{
return *this;
}
// Stage 1:
// Copy all members of oRhs that can throw during copy into temporaries.
// That way if they do throw you have not destroyed this obbject.
// Stage 2:
// Copy anything that can **not** throw from oRhs into this object
// Use swap on the temporaries to copy them into the object in an exception sage mannor.
// Stage 3:
// Free any resources.
return *this;
}
Of course there is a simpler way of doing this using copy and swap idum:
MyObject& MyObject::operator=(MyObject oRhs) // use pass by value to get copy
{
this.swap(oRhs);
return *this;
}
void MyObject::swap(MyObject& oRhs) throws()
{
// Call swap on each member.
return *this;
}
If there is nothing to do in the destructor don't declare it (unless it needs to be virtual).
MyObject::~MyObject(){
//there is nothing here
}
Here you are declaring a pointer (not an object) so the constructor is not called (as pointers don;t have constructors).
const MyObject * mpoOriginal;//this gets initialized in the constructor
Here you are calling new to create the object.
Are you sure you want to do this? A dynamically allocated object must be destroyed; ostensibly via delete, but more usually in C++ you wrap pointers inside a smart pointer to make sure the owner correctly and automatically destroys the object.
int main()
{ //^^^^ Note main() has a lower case m
mpoOriginal = new MyObject();
return DoSomething();
}
But since you probably don't want a dynamic object. What you want is automatic object that is destroyed when it goes out of scope. Also you probably should not be using a global variable (pass it as a parameter otherwise your code is working using the side affects that are associated with global state).
int main()
{
const MyObject mpoOriginal;
return DoSomething(mpoOriginal);
}
You do not need to call new to make a copy just create an object (passing the object you want to copy).
bool DoSomething(MyObject const& data)
{
MyObject poCopied (data); //the copy
//lots of stuff going on
// No need to delete.
// delete poCopied;//this causes the crash - can't step into using GDB
// When it goes out of scope it is auto destroyed (as it is automatic).
return true;
}
What you are doing is making your copy constructor use the assignment operator (which you don't seem to have defined). Frankly I'm surprised it compiles, but because you haven't shown all your code maybe it does.
Write you copy constructor in the normal way, and then see if you still get the same problem. If it's true what you say about 'lots of things ... but I don't see any pointers' then you should not be writing a copy constructor at all. Try just deleting it.
I don't have a direct answer as for what exactly causes the segfault, but conventional wisdom here is to follow the rule of three, i.e. when you find yourself needing any of copy constructor, assignment operator, or a destructor, you better implement all three of them (c++0x adds move semantics, which makes it "rule of four"?).
Then, it's usually the other way around - the copy assignment operator is implemented in terms of copy constructor - copy and swap idiom.
MyObject::MyObject{
lots of things including const and structs, but no pointers
}
The difference between a shallow copy and a deep copy is only meaningful if there is a pointer to dynamic memory. If any of those member structs isn't doing a deep copy of it's pointer, then you'll have to work around that (how depends on the struct). However, if all members either don't contain pointers, or correctly do deep copies of their pointers, then the copy constructor/assignment is not the source of your problems.
It's either, depending on what your operator= does. That's where the magic happens; the copy constructor is merely invoking it.
If you didn't define an operator= yourself, then the compiler synthesised one for you, and it is performing a shallow copy.
I read about this from "Effective c++" ,this is Col.10.
It say it's a good way to have assignment operators return a reference to *this.
I wrote a code snippet to test this idea. I overridden the assignment operator here.And tested it. Everything is fine.
But when I remove that operator overriding, everything is the same. That means, the chaining assignment still works well. So, what am I missing? Why is that? Need some explanation from you guys, THank you.
#include <iostream>
using namespace std;
class Widget{
public:
Widget& operator=(int rhs)
{
return *this;
}
int value;
};
int main()
{
Widget mywidget;
mywidget.value = 1;
Widget mywidget2;
mywidget2.value = 2;
Widget mywidget3 ;
mywidget3.value = 3;
mywidget = mywidget2 = mywidget3;
cout << mywidget.value<<endl;
cout << mywidget2.value<<endl;
cout << mywidget3.value<<endl;
}
If you remove completely the operator= method, a default operator= will be created by the compiler, which implements shallow copy1 and returns a reference to *this.
Incidentally, when you write
mywidget = mywidget2 = mywidget3;
you're actually calling this default operator=, since your overloaded operator is designed to work with ints on the right side.
The chained assignment will stop working, instead, if you return, for example, a value, a const reference (=>you'll get compilation errors) or a reference to something different from *this (counterintuitive stuff will start to happen).
Partially related: the copy and swap idiom, i.e. the perfect way to write an assignment operator. Strongly advised read if you need to write an operator=
The default operator= will perform as if there were an assignment between each member of the left hand operand and each member of the right hand one. This means that for primitive types it will be a "brutal" bitwise copy, which in 90% of cases isn't ok for pointers to owned resources.
The question touches two different concepts, whether you should define operator= and whether in doing so you should return a reference to the object.
You should consider the rule of the three: if you define one of copy constructor, assignment operator or destructor you should define the three of them. The rationale around that rule is that if you need to provide a destructor it means that you are managing a resource, and in doing so, chances are that the default copy constructor and assignment operator won't cut it. As an example, if you hold memory through a raw pointer, then you need to release the memory in the destructor. If you don't provide the copy constructor and assignment operator, then the pointer will be copied and two different objects will try to release the memory held by the pointer.
While a pointer is the most common example, this applies to any resource. The exception is classes where you disable copy construction and assignment --but then again you are somehow defining them to be disabled.
On the second part of the question, or whether you should return a reference to the object, you should. The reason, as with all other operator overloads is that it is usually a good advice to mimic what the existing operators for basic types do. This is sometimes given by a quote: when overloading operators, do as ints do.
Widget& operator=(int rhs)
This allows you to assign an int to a Widget - e.g. mywidget = 3;
Make a Widget& operator=(Widget const & rhs) - it'll be called for your mywidget = mywidget2 = mywidget3; line.
You do not need an operator=(Widget const & rhs) though - the default should do fine.
Also, it may be a good idea to add e.g. cout << "operator=(int rhs)\n"; to your custom operator - then you'd see that it didn't get called at all in your code.
I searched how to implement + operator properly all over the internet and all the results i found do the following steps :
const MyClass MyClass::operator+(const MyClass &other) const
{
MyClass result = *this; // Make a copy of myself. Same as MyClass result(*this);
result += other; // Use += to add other to the copy.
return result; // All done!
}
I have few questions about this "process" :
Isn't that stupid to implement + operator this way, it calls the assignment operator(which copies the class) in the first line and then the copy constructor in the return (which also copies the class , due to the fact that the return is by value, so it destroys the first copy and creates a new one.. which is frankly not really smart ... )
When i write a=b+c, the b+c part creates a new copy of the class, then the 'a=' part copies the copy to himself.
who deletes the copy that b+c created ?
Is there a better way to implement + operator without coping the class twice, and also without any memory issues ?
thanks in advance
That's effectively not an assignment operator, but a copy constructor. An operation like addition creates a new value, after all, so it has to be created somewhere. This is more efficient than it seems, since the compiler is free to do Return Value Optimization, which means it can construct the value directly where it will next be used.
The result is declared as a local variable, and hence goes away with the function call - except if RVO (see above) is used, in which case it was never actually created in the function, but in the caller.
Not really; this method is much more efficient than it looks at first.
Under the circumstances, I'd probably consider something like:
MyClass MyClass::operator+(MyClass other) {
other += *this;
return other;
}
Dave Abrahams wrote an article a while back explaining how this works and why this kind of code is usually quite efficient even though it initially seems like it shouldn't be.
Edit (thank you MSalters): Yes, this does assume/depend upon the commutative property holding for MyClass. If a+b != b+a, then the original code is what you want (most of the same reasoning applies).
it calls the assignment operator(which copies the class) in the first line
No, this is copy-initialization (through constructor).
then the copy constructor in the return (which also copies the class
Compilers can (and typically do) elide this copy using NRVO.
When i write a=b+c, the b+c part creates a new copy of the class, then the 'a=' part copies the copy to himself. who deletes the copy that b+c created
The compiler, as any other temporary value. They are deleted at the end of full-expression (in this case, it means at or after ; at the end of line.
Is there a better way to implement + operator without coping the class twice, and also without any memory issues ?
Not really. It's not that inefficient.
This appears to be the correct way to implement operator+. A few points:
MyClass result = *this does not use the assignment operator, it should be calling the copy constructor, as if it were written MyClass result(*this).
The returned value when used in a = b + c is called a temporary, and the compiler is responsible for deleting it (which will probably happen at the end of the statement ie. the semicolon, after everything else has been done). You don't have to worry about that, the compiler will always clean up temporaries.
There's no better way, you need the copy. The compiler, however, is allowed to optimise away the temporary copies, so not as many as you think may be made. In C++0x though, you can use move constructors to improve performance by transfering ownership of the content of a temporary rather than copying it in its entirity.
I'll try my best to answer:
Point (1): No, it does not call the assignment operator. Instead it calls a constructor. Since you need to construct the object anyway (since operator+ returns a copy), this does not introduce extra operations.
Point (2): The temporary result is created in stack and hence does not introduce memory problem (it is destroyed when function exits). On return, a temporary is created so that an assignment (or copy constructor) can be used to assign the results to a (in a=b+c;) even after result is destroyed. This temporary is destroyed automatically by the compiler.
Point (3): The above is what the standard prescribes. Remember that compiler implementors are allowed to optimize the implementation as long as the effect is the same as what the standard prescribed. I believe, compilers in reality optimize away many of the copying that occurs here. Using the idiom above is readable and is not actually inefficient.
P.S. I sometime prefer to implement operator+ as a non-member to leverage implicit conversion for both sides of the operators (only if it makes sense).
There are no memory issues (provided that the assignment operator, and copy constructor are well written). Simply because all the memory for these objects is taken on the stack and managed by the compiler. Furthermore, compilers do optimize this and perform all the operations directly on the final a instead of copying twice.
This is the proper way of implementing the operator+ in C++. Most of the copies you are so afraid of will get elided by the compiler and will be subject to move semantics in C++0x.
The class is a temporary and will be deleted. If you bind the temporary to a const& the life time of the temporary will be extended to the life time of the const reference.
May implementing it as a freefunction is a little more obvious. The first parameter in MyClass::operator+ is an implicit this and the compiler will rewrite the function to operator+(const MyClass&, const MyClass&) anyway.
As far as I remember, Stroustrup's 'The C++ Programming Language' recommends to implement operators as member functions only when internal representation is affected by operation and as external functions when not. operator+ does not need to access internal representation if implemented based on operator+=, which does.
So you would have:
class MyClass
{
public:
MyClass& operator+=(const MyClass &other)
{
// Implementation
return *this;
}
};
MyClass operator+(const MyClass &op1, const MyClass &op2)
{
MyClass r = op1;
return r += op2;
}
I'm writing an application, where I want to store strings as keys ans a custom Object as value
multimap<string, owncreatedobject> mymap;
Compiling does well, but I get a "Segmentation fault" when using the function insert
during runtime.
mymap.insert(string,myobject); --> Segmentation Error
A already added a copyconstructor an assignmentfunction (which calls the copyconstructor)
any idea about the "Segmentation fault?
Looking at the comment you added for the copy constructor and assignment operator implementation, I found that your assignment operator implementation is wrong. Basically it is not copying anything, instead with the statement Filter(f); , you are creating a local object named f. You can not call copy constructor like that. I suggest you to write a private copy method and use it in both copy ctor and assignment operator.
I fiddle with your problem for the last hour and I think I got it.
Try using something in the matter of this code segment:
multimap<string,yourclass const*> mymap
void addtomap(string s,yourclass const* c)
{
mymap.insert(pair<string, yourclass const*>(s,c));
}
...`addtomap("abc",&z);
In your given example you tried to insert without an iterator. The first element for a 2 element insert call for a multimap is the iterator. That's the reason for your segmentation fault and why one should use pair.
I suspect that you have a buggy copy constructor and/or assignment operator implementation.
If the line
mymap.insert(std::make_pair(mystring,myobject));
crashes, it's pretty likely that some method which is executed on 'myobject' causes the problem. In this code line, the most interesting functions are the copy constructor and/or the assignment operator.
You say that you already added an assignment operator (which calls the copy constructor), but that sounds strange. Usually it's exactly the other way round; the copy constructor allocates resources (i.e. memory) as needed and then calls the assignment operator.
UPDATE: After reading your comment, here's how your copy constructor should look like:
Filter::Filter( const Filter &rhs ) {
// Apparently no resource acquisition like memory allocation is necessary,
// so just assign the rhs value.
*this = rhs;
}
And here's the assignment operator. Note how it just copies over the values. Chances are that you don't need an assignment operator (or copy constructor) implementation at all because the compiler-synthesized code is fine for your uses.
Filter &Filter::operator=( const Filter &rhs ) {
SrcNET = f.SrcNET;
SrcPort = f.SrcPort;
DstNET = f.DstNET;
FlowLabel = f.FlowLabel;
return *this;
}
I assume you're trying to call the insert version that accepts a value_type of the multimap. In this case, just remember that multimap's value_type is a std::pair. Then, try this:
mymap.insert(std::make_pair(mystring,myobject));
EDIT (after your comment): Your assignment operator contains an error. You create a temporary that serves for no purpose. Below is a suggestion of implementation using the swap idiom. (Notice that I don't know what are the types of the class member. Suppose they're a builtin such as int for example.)
void Swap(Filter const& f) //Create a swap member function.
{
std::swap(SrcNET, f.SrcNET);
std::swap(SrcPort, f.SrcPort);
std::swap(DstNET, f.DstNET);
std::swap(DstPort, f.DstPort);
std::swap(FlowLabel, f.FlowLabel);
}
Filter& Filter::operator =(Filter f)
{
swap(f); //Swaps the copy created for parameter passing (pass-by-value) above.
return *this;
}