class A
{
public:
A(){}
~A(){}
void DoSomething(int x){}
};
void func(int i)
{
A *pa = new A();
pa->DoSomething(i);
delete pa;
}
Do you guys see any problem with this code?
I can only see following two:
func is only operating on object of class A and should be made member of A.
object of class A should be created on the stack instead of heap.
Any other ideas?
object of class A should be created on the stack instead of heap.
Yes, pa should be created as an automatic variable (on the stack) instead of dynamically (on the heap).
However, it's also wrong as written because it isn't exception-safe. If pa->DoSomething(i) throws an exception, you will leak the object pointed to by pa.
The correct way to manage resource lifetimes is to use Scope-Bound Resource Management (SBRM; also called Resource Acquisition Is Initialization). The RAII way to manage a dynamically allocated object is to use a smart pointer:
void func(int i)
{
std::auto_ptr<A> pa(new A());
pa->DoSomething(i);
}
Manual resource management is brittle and dangerous because it's easy to get wrong. In this trivial example, it's easy to see that pa->DoSomething(i) does not throw an exception because it doesn't do anything at all. But in almost every real program, it's not that easy.
Manual resource management quickly becomes very difficult as a program grows in size and complexity. Automatic resource management using Scope-Bound Resource Management scales very well.
func is only operating on object of class A and should be made member of A.
This is not correct. You should only implement a function as a member function if it requires access to the internal state of the object. This means that you should prefer to implement functions as non-member functions wherever possible.
The more member functions you have, the more work it takes to thoroughly test a class because there are more ways that the internal state of the class can be modified.
Herb Sutter explains this principle by breaking down the std::string class in his Guru of the Week article "Monoliths Unstrung."
Any exception happens on func() while executing A::DoSomething() cause a memory leak. Use a smart pointer (e.g. std::auto_ptr)
Also, a class that needs a copy constructor, an assignment operator or a destructor typically needs all three (I know, this one is empty - just saying).
Is this real code? Then the stateless class is completely superfluous, and void DoSomething(int x) should be a normal function. If not, post the real code, otherwise it's hard to give further advice.
Related
I have a function call
void moveMeToThread(UnsafeStruct *ptr)
{
// do stuff with ptr
}
Now I want to move moveMeToThread to a different thread, so I do not want anyone creating an object of UnsafeStruct on the stack and I also want memory of all UnsafeStruct objects made on the heap to be freed automatically. Anyone have an elegant way to do this?
Sounds like you'd like to make a heap-only class. There are many ways to force this:
you might make private ctors (all of them!) and create a static create() function that returns a pointer (sometimes called named ctor)
you might make dtor private
The latter technically does not save you from placement new to a suitable memory block, but otherwise protects from sensible coding mistakes and is way more compatible with algorithms and containers. E.g. you can still copy such an object via copy ctor outside the class, which is not possible if you make all ctors private (which is a requirement for the first version).
You might do this:
template<typename T>
class HeapOnly
{
public:
T t;
operator T&() { return t; }
operator const T&() const { return t; }
private:
~HeapOnly();
};
void moveMeToThread(HeapOnly<UnsafeStruct> *ptr)
{ /* ... */ }
int main()
{
HeapOnly<UnsafeStruct> *ptr =
new HeapOnly<UnsafeStruct>{/* args to UnsafeStruct */};
moveToThread(ptr);
}
Small note: there's no such thing as (call/parameter) stack in the C++ standard. It only appears in ItaniumABI (and potentially in other ABIs). Standard says ASDV (automatic storage duration variables) for what's commonly referred to as 'on the stack', but nothing prevents an implementation to allocate the memory on the stack (as long as compiler can prove that the object's lifetime cannot extend the stack unroll - this works e.g. if it's allocated before static initialization). It might be completely unimportant in your case, but in security-related codes, where buffer overflow is important, you can't strictly enforce not having objects allocated from the same stack this way (and thus it's suggested to do a runtime check) - but you can still enforce that the object is allocated via new (or the given static member function).
I do not want anyone creating an object of UnsafeStruct on the stack.
I want to forbid it because if someone creates an object on the stack and sends it on the thread, it can cause a crash(dangling pointer)
Do you also want to prevent anybody from creating int variables on the stack? Because if somebody creates an int variable on the stack, and if they allow a reference or a pointer to it to outlive the stack frame that contains the variable, then their program could crash.
Seriously.
That problem is older than C++. That problem has existed since the very first edition of the C programming language. Every C and C++ programmer has to learn not to do that. Always have. Always will.
In some languages (e.g., Java, Python), No object of any kind can be allocated anywhere else except the garbage-collected heap. Variables can only hold references to objects, and dangling references are impossible. Programmers in those languages expect an assignment a=b to copy an object reference. That is, after the assignment, a and b both refer to the same object.
That's not the C++ way. C++ programmers expect that if some type T is publicly constructable, then they expect to be allowed to declare one wherever they want. And when they see a=b, they think of that assignment operator as copying a value. They expect that after the assignment, a and b still are two different objects that both have (in some sense) the same "value."
You will find more people saying positive things about your library if you design it to work in that same way.
There was a question asked about what a C++
wrapper class is, and I think he provided a good answer. His username: GManNickG from Stack Overflow provided the following code with his answer:
class int_ptr_wrapper
{
public:
int_ptr_wrapper(int value = 0) :
mInt(new int(value))
{}
// note! needs copy-constructor and copy-assignment operator!
~int_ptr_wrapper()
{
delete mInt;
}
private:
int* mInt;
};
That code prompted me with a question. I've heard from several different people that its considered bad practice to use the new and delete keywords.
Is there a certain situation in which I should use new or delete? Also If I wrote the code above like below, which is considered better practice?
class int_ptr_wrapper
{
public:
int_ptr_wrapper(int value = 0) :
m_int(&value) {}
private:
int* m_int;
};
There is (almost) always a better way than using new. There is absolutely always a better way than using delete.
Have a look at the documentation for std::shared_ptr<> and std::unique_ptr<>. Between them they cover every scenario you will ever need with regard to scoped memory management, automatic releasing of memory resources, automatic closing of files, automatic zeroing out of memory used for encryption... and so on. This is because both classes give you the opportunity to provide a custom deleter, so no matter how complex your memory deallocation needs, they're covered flawlessly and safely.
Writing a complete scoped memory manager class is harder than it at first seems. The c++ standard has done it for you. There is no good argument to reinvent that particular wheel.
i was wondering if it is possible to force an object to be created on the heap by creating a private/protected desctuctor and by using shared_ptrs to ensure an automatic resource managment (the RAII features of a shared_ptr) at the same time.
Can that be done in a different way maybe?
The reason i ask that, is because from what i heard(didnt look at that yet) at the STL there are no virtual descructors,so there is no way to ensure safe destruction other than...shared_ptr?
And if so,there is no way to force the object to the heap since shared_ptr is trying to access the destuctor.
Anyway to bypass these limitations?
C++ is a language that puts the correctness of the code in the hand of the programmer. Trying to alter that via some convoluted methods typically leads to code that is hard to use or that doesn't work very well. Forcing the hand of the programmer so that (s)he has to create an object on the heap even if that's not "right" for that particular situation is just bad. Let the programmer shoot him-/herself in the foot if he wants to.
In larger projects, code should be reviewed by peers (preferably at least sometimes by more senior staff) for correctness and that it follows the coding guidelines of the project.
I'm not entirely sure how "virtual destructors" relate to "safe destruction" and "shared pointers" - these are three different concepts that are not very closely related - virtual destructors are needed when a class is used as a base-class to derive a new class. STL objects are not meant to be derived from [as a rule, you use templates OR inheritance, although they CAN be combined, it gets very complicated very quickly when you do], so there is no need to use virtual destructors in STL.
If you have a class that is a baseclass, and the storage is done based on pointers or references to the baseclass, then you MUST have virtual destructors - or don't use inheritance.
"safe destruction", I take it, means "no memory leaks" [rather than "correct destruction", which can of course also be a problem - and cause problems with memory leaks]. For a large number of situations, this means "don't use pointers to the object in the first place". I see a lot of examples here on SO where the programmer is calling new for absolutely no reason. vector<X>* v = new vector<X>; is definitely a "bad smell" (Just like fish or meat, something is wrong with the code if it smells bad). And if you are calling new, then using shared pointer, unique pointer or some other "wrapping" is a good idea. But you shouldn't force that concept - there are occasionally good reasons NOT to do that.
"shared pointer" is a concept to "automatically destroy the object when it is no longer in use", which is a useful technique to avoid memory leaks.
Now that I have told you NOT to do this, here's one way to achieve it:
class X
{
private:
int x;
X() : x(42) {};
public:
static shared_ptr<X> makeX() { return make_shared<X>(); }
};
Since the constructor is private, the "user" of the class can't call "new" or create an object of this kind. [You probably also want to put the copy constructor and assignment operator in private or use delete to prevent them from being used].
However, I still think this is a bad idea in the first place.
The answer by Mats is indeed wrong. The make_shared needs a public constructor.
However, the following is valid:
class X
{
private:
int x;
X() : x( 42 ) {};
public:
static std::shared_ptr<X> makeX()
{
return std::shared_ptr<X>( new X() );
}
};
I don't like to use the new keyword, but in this case, it is the only way.
I enjoy using the operators new and delete in C++ a lot but often have a problem calling delete later on in the program's code.
For example, in the following code:
class Foo {
public:
string *ace;
Foo();
~Foo();
};
Foo::Foo() {
ace = new string;
}
Foo::~Foo() {
delete ace;
}
void UI::ButtonPressed() { //Happens when an event is triggered
Foo *foo = new Foo;
ui->label = ace; //Set some text on the GUI
delete foo; //Calls the destructor, deleting "ace" and removing it from the GUI window
}
I can declare a new string but when I delete it, it removes the value from the GUI form because that string has now been deleted.
Is there a way for me to delete this allocated string somehow later on?
I don't want to declare it as a global variable and then delete it on the last line of the program's source code. I could just never call delete but from what I have been taught that's bad and results in memory leaks.
You should read about the RAII pattern. It is one of the most important concepts to know for a C++ programmer.
The basic idea is that the lifetime of a resource (a new'ed object, an HTTP connection, etc.) is tied to the lifetime of an object. This is necessary in order to write exception safe code.
In your case, the UI widget would make a copy of the object and free it in its own destructor. The calling code could then free its copy right away (in another destructor).
If you are using std::string for both ace and ui->label then you don't have to worry about the memory for foo->ace being deleted once the foo object goes out of scope.
A copy of the Right-Hand argument is made available to ui->label on an = (assignment operation). You can read more about it on the C++ std::string reference page for string::operator=.
Also, such problems can be avoided in full by using smart pointers, such as the ones provided by the boost library. Read this great post on stackoverflow on this subject to get a better understanding.
Well, there's a lot to say of your code. Some things have already been said, e.g. that you should make string a normal member so the allocation/deallcoation issue goes away completely (that's a general rule for C++ programs: If you don't absolutely have to use dynamic allocation, then don't, period). Also, using an appropriate smart pointer would do the memory management for you (also a general rule in C++: Don't manage the dynamic allocations yourself unless you really have to).
However let's pretend that you have to use dynamic allocation, and you have to use raw pointers and direct new and delete here. Then another important rule comes in (which actually isn't a C++ specific rule, but a general OO rule): Don't make the member public. Make it a private member, and offer a public member function for setting it. That public member function then can properly delete the old object before assigning the pointer to the new one. Note that as soon as you assigned the pointer, unless you've stored the old value elsewhere, the old value is lost forever, and if the object has not been deleted up to then, you can't delete it later.
You also want to consider whether it is really a good idea to take ownership of an object passed to you by pointer (and assigning to a pointer member which has a delete in the destructor is a ― not very obvious ― way to pass ownership). This complicates the object lifetime management because you have to remember whether you passed a certain object to an ownership-claiming object (this is not an issue if you have a strict policy of always passing to ownership-claiming objects, though). As usual, smart pointers may help here; however you may consider whether it is a better option to make a copy of the passed object (for std::string it definitely is, but then, here it's better to have a direct member anyway, as mentioned above).
So here's a full list of rules, where earlier rules take precedence to later unless there's a good reason not to use it:
Don't use dynamical allocation.
Manage your dynamical allocation with smart pointers.
Use new only in constructors and delete only in the corresponding destructor.
Always have the new and delete for a specific pointer in member functions of the same class. (Actually the previous rule is a special case of this one, but a special case which should be preferred to the general one.)
Here's a more idiomatic C++ program:
class Foo {
public:
std::string ace;
Foo() : ace() {
// nothing to do here. ace knows how to create itself…
}
// and copy itself…
Foo(const Foo& other) : ace(other.ace) {}
// and clean up after itself…
~Foo() {
}
// and copy/assign itself…
Foo& operator=(const Foo& other) {
this->ace = other.ace;
return *this;
}
};
void UI::ButtonPressed() {
// `new` is not needed here, either!
Foo foo;
ui->label = foo.ace; //Set some text on the GUI
// `delete` is not needed here
}
If you really need to call new, always use an appropriate smart pointer -- Writing delete is banished from modern C++ ;)
I'm coming from C# and trying to translate some of my practices into C++. I've used dependency injection in various places throughout my code using raw pointers. Then I decide to replace the raw pointers with std::shared_ptr's. As part of that process it was suggested that I consider using stack allocated automatic variables rather than dynamically allocating them (see this question although that question was in the context of unique_ptr so maybe that is different).
I believe the below example shows the use of automatic variables.
class MyClass
{
public:
MyClass(ApplicationService& app): appService_(app)
{
}
~MyClass()
{
appService_.Destroy(something);
}
private:
ApplicationService& appService_;
}
class ConsumerClass
{
DoSomething()
{
CustomApplicationService customAppService;
MyClass myclass(customAppService);
myclass...
}
}
In the above example, when customAppservice and myclass go out of scope how do I know which will be destroyed first? If customAppService is destroyed first than the MyClass destructor will fail. Is this a good reason to use shared_ptr instead in this scenario or is there a clean way around this?
UPDATE
ApplicationService is a class that is a wrapper around global functions needed to interact with a 3rd party library that my code uses. I have this class as I believe it's the standard way to support unit testing and stubbing/mocking of free standing functions. This class simply delegates calls to the corresponding global functions. The call appService_.Destroy(something); is actually destroying an object used by each specific instance of MyClass not destroying anything do with the Application class itself.
The answer is: you don't need to know, as your design is broken, anyway.
First, a Destroy sounds like a bad idea, furthermore if called in an object that is not responsible for the destruction of the other object. The code from the Destroy method belongs into ApplicationService's destructor (which is hopefully virtual, although in this case it doesn't actually need to), which in contrast to C# gets called at a perfectly determined point in time.
Once you've done this, you will (hopefully) realize, that it is not the responsibility of MyClass to destroy the appService_, as it does not own it. It is the responsibility of the ConsumerClass (or rather the DoSomething method), which really manages the actual service and which does actually destroy it automatically once you've moved Destroy's code into the destructor. Isn't it nice how RAII does make happen everything in a clean and automatic way?
class MyClass
{
public:
MyClass(ApplicationService& app): appService_(app)
{
}
private:
ApplicationService& appService_;
}
class ConsumerClass
{
DoSomething()
{
CustomApplicationService customAppService;
MyClass myclass(customAppService);
myclass...
}
}
class ApplicationService
{
public:
virtual ~ApplicationService()
{
//code from former Destroy method
}
}
class CustomApplicationService
{
public:
virtual ~CustomApplicationService()
{
//code from former Destroy method
}
}
This is IMHO the perfect clean C++ way around it and the problem is definitely not a reason to spam shared_ptrs. Even if you really need a dedicated Destroy method and cannot move the code into the destructor (which I would take as a motivation for overthinking the design), then you would still call Destroy from DoSomething as again, MyClass is not responsible for destroying the appService_.
EDIT: According to you update (and my stupid overlooking of the something argument), your design seems indeed quite correct (at least if you cannot mess with changing the ApplicationService), sorry.
Allthough class members should get destroyed in reverse order of construction, I'm not sure this also holds for local automatic variables. What you could do to make sure the destructors get called in a defined order is introduce nested scopes using simple blocks:
void DoSomething()
{
CustomApplicationService customAppService;
{
MyClass myclass(customAppService);
myclass...
} // myclass destroyed
} // customAppService destroyed
Of course there is still completely no need to use dynamic allocation, let aside shared_ptrs. Although the nested blocks blow the code a bit, it is nothing against the ugliness of dynamic allocation applied in a non-dynamic way and without reason and it at least "looks nice in a semantic way" with customAppService's declaration on top of the block ;)
In C++, objects, in general, are destroyed in the order that is exact opposite of the order they were created in.
Based on your example, MyClass will be destroyed before CustomApplicationService
The exception is when a destructor is called explicitly. However, I don't think you should concern yourself with this exception at this stage.
Another subtlety is called static initialization order fiasco . However, this does not apply to automatic (stack) variables.
Edit:
From C++2003 - looked for 'reverse order'
6.6.0.2
On exit from a scope (however accomplished), destructors (12.4) are called for all
constructed objects with automatic storage duration (3.7.2) (named objects or
temporaries) that are declared in that scope, in the reverse order of their
declaration. ... [Note: However, the program can be terminated (by calling exit()
or abort()(18.3), for example) without destroying class objects with automatic
storage duration. ]