Does this C++ code leak memory? - c++

struct Foo
{
Foo(int i)
{
ptr = new int(i);
}
~Foo()
{
delete ptr;
}
int* ptr;
};
int main()
{
{
Foo a(8);
Foo b(7);
a = b;
}
//Do other stuff
}
If I understand correctly, the compiler will automatically create an assignment operator member function for Foo. However, that just takes the value of ptr in b and puts it in a. The memory allocated by a originally seems lost. I could do a call a.~Foo(); before making the assignment, but I heard somewhere that you should rarely need to explicitly call a destructor. So let's say instead I write an assignment operator for Foo that deletes the int pointer of the left operand before assigning the r-value to the l-value. Like so:
Foo& operator=(const Foo& other)
{
//To handle self-assignment:
if (this != &other) {
delete this->ptr;
this->ptr = other.ptr;
}
return *this;
}
But if I do that, then when Foo a and Foo b go out of scope, don't both their destructors run, deleting the same pointer twice (since they both point to the same thing now)?
Edit:
If I understand Anders K correctly, this is the proper way to do it:
Foo& operator=(const Foo& other)
{
//To handle self-assignment:
if (this != &other) {
delete this->ptr;
//Clones the int
this->ptr = new int(*other.ptr);
}
return *this;
}
Now, a cloned the int that b pointed to, and sets its own pointer to it. Perhaps in this situation, the delete and new were not necessary because it just involves ints, but if the data member was not an int* but rather a Bar* or whatnot, a reallocation could be necessary.
Edit 2:
The best solution appears to be the copy-and-swap idiom.

Whether this leaks memory?
No it doesn't.
It seems most of the people have missed the point here. So here is a bit of clarification.
The initial response of "No it doesn't leak" in this answer was Incorrect but the solution that was and is suggested here is the only and the most appropriate solution to the problem.
The solution to your woes is:
Not use a pointer to integer member(int *) but to use just an integer (int), You don't really need dynamically allocated pointer member here. You can achieve the same functionality using an int as member.
Note that in C++ You should use new as little as possible.
If for some reason(which I can't see in the code sample) You can't do without dynamically allocated pointer member read on:
You need to follow the Rule of Three!
Why do you need to follow Rule of Three?
The Rule of Three states:
If your class needs either
a copy constructor,
an assignment operator,
or a destructor,
then it is likely to need all three of them.
Your class needs an explicit destructor of its own so it also needs an explicit copy constructor and copy assignment operator.
Since copy constructor and copy assignment operator for your class are implicit, they are implicitly public as well, Which means the class design allows to copy or assign objects of this class. The implicitly generated versions of these functions will only make a shallow copy of the dynamically allocated pointer member, this exposes your class to:
Memory Leaks &
Dangling pointers &
Potential Undefined Behavior of double deallocation
Which basically means you cannot make do with the implicitly generated versions, You need to provide your own overloaded versions and this is what Rule of Three says to begin with.
The explicitly provided overloads should make a deep copy of the allocated member and it thus prevents all your problems.
How to implement the Copy assignment operator correctly?
In this case the most efficient and optimized way of providing a copy assignment operator is by using:
copy-and-swap Idiom
#GManNickG's famous answer provides enough detail to explain the advantages it provides.
Suggestion:
Also, You are much better off using smart pointer as an class member rather than a raw pointer which burdens you with explicit memory management. A smart pointer will implicitly manage the memory for you. What kind of smart pointer to use depends on lifetime and ownership semantics intended for your member and you need to choose an appropriate smart pointer as per your requirement.

the normal way to handle this is to create a clone of the object the pointer points to, that is why it is important to have an assignment operator. when there is no assigment operator defined the default behavior is a memcpy which will cause a crash when both destructors try to delete the same object and a memory leak since the previous value ptr was pointing to in b will not be deleted.
Foo a
+-----+
a->ptr-> | |
+-----+
Foo b
+-----+
b->ptr-> | |
+-----+
a = b
+-----+
| |
+-----+
a->ptr
\ +-----+
b->ptr | |
+-----+
when a and b go out of scope delete will be called twice on the same object.
edit: as Benjamin/Als correctly pointed out the above is just referring to this particular example, see below in comments

The code as presented has Undefined Behavior. As such, if it leaks memory (as expected) then that is just one possible manifestation of the UB. It can also send an angry threatening letter to Barack Obama, or spew out red (or orange) nasal daemons, or do nothing, or act as if there was no memory leak, miraculously reclaiming the memory, or whatever.
Solution: instead of int*, use int, i.e.
struct Foo
{
Foo(int i): blah( i ) {}
int blah;
};
int main()
{
{
Foo a(8);
Foo b(7);
a = b;
}
//Do other stuff
}
That’s safer, shorter, far more efficient and far more clear.
No other solution presented for this question, beats the above on any objective measure.

Related

C++ custom delete

Let's say we have the following code:
class MyType
{
public: int x;
}
MyType* object = new MyType();
delete object;
Is there a possible to check if object has specific value of x before deletion?
For example, if object.x is odd number, the object should not be free from memory after delete is called. In a few words to make a custom delete for this class where we can choose when the object can be free at operator delete call.
What is the real issue you are trying to solve?
To begin with, this Q&A is a good lesson to the common scenario in C++ of:
The language allowing you to do something, but just because you can doesn't mean you should.
These scenarios are commonly run into when trying to solve an XY problem.
In this particular case, instead of trying to overload operator delete (solving the Y problem, to much confusion of the clients of MyType) you are likely looking for something entirely different (the X problem), say a resource manager that take responsibility of MyType resources w.r.t. if and when they should be deleted (or not), based on e.g. object traits (such as oddness of a data member). See e.g. #Ayxan Haqverdili's answer for a minimal example.
A look at theoretically solving the misidentified Y problem
Don't do this, ever, for this kind of use case.
You can overload operator delete (as well as operator delete[]), by defining it as a static member function of the class for which you want to overload it (lookup precedence by lexical scope). As pointed out in the comments, whilst overloading the usual deallocation functions is legal, trying to conditionally allow for it to be called more than once is not:
struct MyType final {
int x;
static void operator delete(void *p) {
if (static_cast<MyType *>(p)->x % 2 == 1) {
::operator delete(p);
}
}
};
int main() {
MyType *object = new MyType{42};
delete object; // Not DEALLOCATED.
// Underlying object DESTRUCTED, however.
// Extremely confusing.
++(object->x);
delete object; // UB: destructor for underlying object called twice.
}
as per [expr.delete]/6 [emphasis mine]:
If the value of the operand of the delete-expression is not a null pointer value and the selected deallocation function (see below) is not a destroying operator delete, the delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted.
As a second attempt (emphasis: don't ever go down this road), we could avoid the destructor being called (only calling it conditionally) by overloading and abusing the (new as of C++20) class-specific destroying deallocation functions:
#include <iostream>
#include <new>
struct MyType final {
int x;
static void operator delete(MyType *p, std::destroying_delete_t) {
if (p->x % 2 == 1) {
p->~MyType();
::operator delete(p);
}
}
~MyType() {
std::cout << "\ndtor";
}
};
int main() {
MyType *object = new MyType{42};
delete object; // Neither deallocated nor underlying object destructed.
++(object->x);
delete object; // Destructed and deallocated.
}
Afaict this program is well-formed, but it does abuse the new destroying delete overloads. Clang does emit a -Wmismatched-new-delete warning, which is typically a hint for UB, but it may be inaccurate here.
Anyway, this seems like a good place to stop the fruitless journey of addressing this particular Y problem.
Yes:
if (object->x % 2 == 1)
delete object;
Note that raw pointers should be used rarely and with a lot of care.

Array class member initialization in C++

I have the following code snippet:
#include <iostream>
using namespace std;
class A {
int* data;
int size;
public:
A(int s):size(s)
{
data = new int[size];
}
A() {
data = nullptr;
}
~A() {
if (data) delete [] data;
}
};
class B {
A a[2];
public:
B() {
a[0] = A(10);
a[1] = A(11);
}
};
int main(int argc, char *argv[]) {
B b;
}
In the C++ code above, I have class A which has an array member int* data, and the (de)allocation of memory are handled by (de)constructor. The I created class B which has an array of class A of fixed length as a data member.
My question is: how to elegantly initialise the member A a[2]? In the code above, the A(10) and A(11) are created on the stack, when jumping out of the scope, their destructors will be called, hence the data comes invalid. When jumping of the main function's scope, the pointers held by a[2] will be deallocated twice, causing the error:
pointer being freed was not allocated.
One possible solution is to carefully design a copy constructor and a move constructor, by doing so the above coding paradigm could work.
Another solution I've tried is to initialise the array in the initialization list of class B:
B() : a { A(10), A(11) }
This solution works and I don't really tell the underlying mechanism of initialization list. I think it must be quite different from simply construct and copy. I really expected some experts could give an elaborate explanation of this mechanism. Of course, this solution is ugly hard-coded and not flexible.
So I wonder if there are some programming paradigms in C++ to tackle this design problem?
In the code above, the A(10) and A(11) are created on the stack
They are temporary objects. It is not specified where they are created or if they're created at all.
when jumping out of the scope, their destructors will be called
The destructor of each temporary will be called after the corresponding move assignment statement ends.
One possible solution is to carefully design a copy constructor and a move constructor, by doing so the above coding paradigm could work.
And {copy,move} assignment operator too. You should always do that when the implicitly declared ones don't do the right thing. And they never do the right thing if you delete something in the destructor.
Another solution I've tried is to initialise the array in the initialization list of class B
This solution works and I don't really tell the underlying mechanism of initialization list. I think it must be quite different from simply construct and copy.
The bug in the original code is badly behaving move assignment operator of A. Since the initialization list never move assigns from a temporary, it never triggers the bug.
This is actually the more elegant way to construct a that you asked for. Not because it avoids the bug, but because avoiding unnecessary moving is good thing, intrinsically.
So I wonder if there are some programming paradigms in C++ to tackle this design problem?
Yes. RAII and Single responsibility principle. Unless your class does nothing else, besides managing the memory pointed by data, it should not be managing the memory. Instead, it should delegate the memory management to a RAII object. In this case, you should use a std::vector member.
class A {
std::vector<int> data;
public:
A(int s):data(s) {}
A() = default;
};
Using an initializer list to construct B::a, like this:
class B {
A a[2];
public:
B() : a({10, 11}){
}
};
The ideal answer would be to force A to use movements instead of copies, or on a copy to allocate new space for the item. Of the two, the most efficient is the former and so I will expand on it below:
Forcing movement can be done in two fashions:
Delete the copy constructor and copy operator=, and implement your own move constructor and operator=
Consistently use std::move and std::swap.
Of these, the former is superior in that you will be unable to accidentally copy the class, but with the latter the fact that you are moving will be more evident.
To delete the default copy methods do:
class A {
A( const A& a ) = delete;
A& operator =( const A& a ) = delete;
}

calling copy constructor and operator= for class data members

Below is an example code (for learning purpose only). Classes A and B are independent and have copy contructors and operators= .
class C
{
public:
C(string cName1, string cName2): a(cName1), b(new B(cName2)) {}
C(const C &c): a(c.a), b(new B(*(c.b))) {}
~C(){ delete b; }
C& operator=(const C &c)
{
if(&c == this) return *this;
a.operator=(c.a);
//1
delete b;
b = new B(*(c.b));
//What about this:
/*
//2
b->operator=(*(c.b));
//3
(*b).operator=(*(c.b));
*/
return *this;
}
private:
A a;
B *b;
};
There are three ways of making assignment for data member b. In fact first of them calls copy constructor. Which one should I use ? //2 and //3 seems to be equivalent.
I decided to move my answer to answers and elaborate.
You want to use 2 or 3 because 1 reallocated the object entirely. You do all the work to clean up, and then do all the work to reallocate/reinitialized the object. However copy assignment:
*b = *c.b;
And the variants you used in your code simply copy the data.
however, we gotta ask, why are you doing it this way in the first place?
There are two reasons, in my mind, to have pointers as members of the class. The first is using b as an opaque pointer. If that is the case, then you don't need to keep reading.
However, what is more likely is that you are trying to use polymorphism with b. IE you have classes D and E that inherit from B. In that case, you CANNOT use the assignment operator! Think about it this way:
B* src_ptr = new D();//pointer to D
B* dest_ptr = new E();//pointer to E
*dest_ptr = *src_ptr;//what happens here?
What happens?
Well, the compiler sees the following function call with the assignment operator:
B& = const B&
It is only aware of the members of B: it can't clean up the no longer used members of E, and it can't really translate from D to E.
In this situation, it is often better to use situation 1 rather than try to decern the subtypes, and use a clone type operator.
class B
{
public:
virtual B* clone() const = 0;
};
B* src_ptr = new E();//pointer to D
B* dest_ptr = new D();//pointer to E, w/e
delete dest_ptr;
dest_ptr = src_ptr->clone();
It may be down to the example but I actually don't even see why b is allocated on the heap. However, the reason why b is allocate on the heap informs how it needs to be copied/assigned. I think there are three reasons for objects to be allocated on the heap rather than being embedded or allocated on the stack:
The object is shared between multiple other objects. Obviously, in this case there is shared ownership and it isn't the object which is actually copied but rather a pointer to the object. Most likely the object is maintained using a std::shared_ptr<T>.
The object is polymorphic and the set of supported types is unknown. In this case the object is actually not copied but rather cloned using a custom, virtual clone() function from the base class. Since the type of the object assigned from doesn't have to be the same, both copy construction and assignment would actually clone the object. The object is probably held using a std::unique_ptr<T> or a custom clone_ptr<T> which automatically takes care of appropriate cloning of the type.
The object is too big to be embedded. Of course, that case doesn't really happen unless you happen to implement the large object and create a suitable handle for it.
In most cases I would actually implement the assignment operator in an identical form, though:
T& T::operator=(T other) {
this->swap(other);
return *this;
}
That is, for the actual copy of the assigned object the code would leverage the already written copy constructor and destructor (both are actually likely to be = defaulted) plus a swap() method which just exchanges resources between two objects (assuming equal allocators; if you need to take case of non-equal allocators things get more fun). The advantage of implementing the code like this is that the assignment is strong exception safe.
Getting back to your approach to the assignment: in no case would I first delete an object and then allocate the replace. Also, I would start off with doing all the operations which may fail, putting them into place at an appropriate place:
C& C::operator=(C const& c)
{
std::unique_ptr tmp(new B(*c.b));
this->a = c.a;
this->b = tmp.reset(this->b);
return *this;
}
Note that this code does not do a self-assignment check. I claim that any assignment operator which actually only works for self-assignment by explicitly guarding against is not exception-safe, at least, it isn't strongly exception safe. Making the case for the basic guarantee is harder but in most cases I have seen the assignment wasn't basic exception safe and your code in the question is no exception: if the allocation throws, this->b contains a stale pointer which can't be told from another pointer (it would, at the very least, need to be set to nullptr after the delete b; and before the allocation).
b->operator=(*(c.b));
(*b).operator=(*(c.b));
These two operations are equivalent and should be spelled
*this->b = *c.b;
or
*b = *c.b;
I prefer the qualified version, e.g., because it works even if b is a base class of template inheriting from a templatized base, but I know that most people don't like it. Using operator=() fails if the type of the object happens to be a built-in type. However, a plain assignment of a heap allocated object doesn't make any sense because the object should be allocated on the heap if that actually does the right thing.
If you use method 1 your assignment operator doesn't even provide the basic (exception) guarantee so that's out for sure.
Best is of course to compose by value. Then you don't even have to write your own copy assignment operator and let the compiler do it for you!
Next best, since it appears you will always have a valid b pointer, is to assign into the existing object: *b = *c.b;
a = c.a;
*b = *c.b;
Of course, if there is a possibility that b will be a null pointer the code should check that before doing the assignment on the second line.

Explanation for below code snippet C++

I was reading C++11 Faq and came across this code. I have a better understanding of C++ coding, but I'm still not able to understand the below code.
template<class T>
class Handle {
T* p;
public:
Handle(T* pp) : p{pp} {}
~Handle() { delete p; } // user-defined destructor: no implicit copy or move
Handle(Handle&& h) :p{h.p} { h.p=nullptr; }; // transfer ownership
Handle& operator=(Handle&& h) { delete p; p=h.p; h.p=nullptr; return *this; } // transfer ownership
Handle(const Handle&) = delete; // no copy
Handle& operator=(const Handle&) = delete;
// ...
};
What does "transfer ownership" mean?
Why is the copy ctor equated to "delete"? how is it useful?
Please if someone can add a few examples with explanation, it would be a great help.
It's a move constructor, the special && syntax introduced in C++11 takes a rvalue reference, so a reference to a variable which has no name and can't be referenced anywhere else inside the code.
What happens in the constructor is that the Handle takes the ownership of the Handle passed through the move constructor in the way that it steals (pass me the term) the T* p inside by assigning its value to its own variable and then setting nullptr to the variable of the rvalue passed.
This is used because you don't really need to copy an rvalue, since that value won't be used anymore in the code, so it's safe to just take its data, this avoids a, possibly costly, copy constructor.
In C++ you had copy constructors and copy operators, which were expensive if your object was big. Now in C++11 you have move constructor and move operator which says "take everything from the source and kill it".
mybigthing y ;
...
mybigthing x( move(y)) ;
y is created with lots of stuff internally. after x(y), y is now empty and all the big stuff is in x.
One of the main reasons for this is to make returning big objects from functions free:
mybigthing f()
{
mybigthing tmp ;
...
return tmp ;
}
{
mybigthing y= f() ;
}
In c++03, this would be horrible performance wise. Now its free. The compilers are required to actually use y as the temporary inside of f() and never do any copies.
transfer ownership means if you do a=b the contents of b belong to a and does not exist in b anymore. This makes more sense in the example {A a; dosomething(a); return a;}. a exist locally in the function. It's contents are being moved into the return value. If A is a typedef for std::string it would mean the string internals have been moved instead of making a copy of a intentionally long string (html page maybe). However I believe string has a copy on write flag so it wouldn't make a copy in that situation but other classes may not bother to implement a copy on write.
The reason the constructor and assignment operator (which are move, not copy) delete is because the current p may be pointing to something. Not freeing it means a memory leak.
about your second question:
Why is the copy ctor equated to "delete"? how is it useful?
Here is an answer:
http://www.developerfusion.com/article/133063/constructors-in-c11/
C++11 Explicitly Deleted Constructors
C++11 also supports the concept of explicitly deleted constructors.
For example, you can define a class for which you do not want to write
any constructors and you also do not want the compiler to generate the
default constructor. In that case you need to explicitly delete the
default constructor:
class MyClass { public:
MyClass() = delete; };

Best way to overload the C++ assignment operator

I have a class A which dynamically allocates memory for an integer(pointed by a class memeber say _pPtrMem) in its constructor and deallocates the same in destructor. To avoid Shallow copy, I have overloaded assignment operator and copy constructor. The widely used way in which assignment operator is overloaded is as following:
A& operator = (const A & iToAssign)
{
if (this == & iToAssign) // Check for self assignment
return *this;
int * pTemp = new int(*(iToAssign._pPtrMem)); // Allocate new memory with same value
if (pTemp)
{
delete _pPtrMem; // Delete the old memory
_pPtrMem = pTemp; // Assign the newly allocated memory
}
return *this; // Return the reference to object for chaining(a = b = c)
}
Another way for implementing the same could be
A& operator = (const A & iToAssign)
{
*_pPtrMem= *(iToAssign._pPtrMem); // Just copy the values
return *this;
}
Since the second version is comparatively much simpler and faster(no deallocation, allocation of memory) why is it not used widely? Any problems that I am not able to make out?
Also we return an object of the same type from the assignment operator for chaining(a = b = c)... so instead of returning *this is it fine to return the iToAssign object as both objects are supposedly now equal?
Usually, the best way to implement a copy assignment operator is to provide a swap() function for your class (or use the standard one if it does what you want) and then implement the copy assignment operator via the copy constructor:
A& A::operator= (A iToAssign) // note pass by value here - will invoke copy constructor
{
iToAssign.swap(*this);
return *this;
}
// void swap(A& other) throws() // C++03
void A::swap(A& other) noexcept
{
std::swap(_pPtrMem, other._pPtrMem);
}
This makes sure that your copy assignment operator and copy constructor never diverge (that is, it cannot happen that you change one and forget to change the other).
No, there is no problem with your implementation. But having one integer dynamic allocated is at least very special.
This implementation is not widely used, because no one allocates a single integer on the free store. You usually use dynamic allocated memory for arrays with a variable length unknown at compile time. And in this case it's most of the time a good idea to just use std::vector.
No it's not fine, to return an different object. Identity is not the same as equality:
T a, b, d;
T& c = a = b;
c = d; // should change a, not b
Would you expect that the third line changes b?
Or a event better Example:
T a;
T& b = a = T();
This would result in a dangling reference, referencing an temporary and destructed object.
The first version is used in case _pPtrMem is a pointer to some basic type for instance a dynamically allocated array. In case the pointer is pointing to a single object with correctly implemented assignment operator the second version will do just as good. But in that case I don't think you will need to use a pointer at all.
In the second case, if _pPtrMem was initially unassigned, the line
*_pPtrMem= *(iToAssign._pPtrMem); // Just copy the values
is causing an assignment to an invalid memory location (possibly a segmentation fault). This can only work if _pPtrMem has been allocated memory prior to this call.
In this case, the second implementation is by far the better.
But the usual reason for using dynamic in an object is because
the size may vary. (Another reason is because you want the
reference semantics of shallow copy.) In such cases, the
simplest solution is to use your first assignment (without the
test for self-assignment). Depending on the object, one might
consider reusing the memory already present if the new value
will fit; it adds to the complexity somewhat (since you have to
test whether it will fit, and still do the
allocation/copy/delete if it doesn't), but it can improve
performance in certain cases.