As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
In C or C++ when we delete some pointer, it only frees the memory but does not set the pointer to 0. Since we can not check the validity of a pointer, it would have been easier for the programmer to check the nullness of the pointer if the pointer is set to 0 after freeing the memory.
I was just wondering why 'delete' is implemented only to free the memory.
“Since we can not check the validity of a pointer, it would have been easier for the programmer to check the nullness of the pointer if the pointer is set to 0 after freeing the memory.”
Checking for nullvalue is likely to hide bugs while increasing the code size and complexity, plus giving a false sense of security. There is no guarantee that the pointer value (before nulling) hasn't been copied elsewhere. Also, this prevents delete by value, which is a major annoyance with libraries (such as OpenCV) that, misguided, offer nulling delete operations.
Instead of such counter-productive practice, use techniques that ensure proper cleanup and prevent invalid pointers, such as using appropriate smart pointers.
Because, in C++, it (almost) all about performance. You don't want the compiler to add code, you don't need. You don't want your program to do things, that you haven't added them in your code.
If you're sure, that on one will check/reuse this pointer, there's no need for annulling. One instruction less.
Also, if deleting a pointer, sets it to NULL, what will happen with the other pointers, that point to the already deleted memory? They will not be annulled. This could lead to bad things.
Just assign NULL, if you need it.
There's no need: Since you only delete in the destructor of your SBRM wrapper class, there's nothing else that could possibly access the pointer afterwards:
template <typename T> struct MyPtr
{
template <typename ...Args> MyPtr(Args &&... args)
: p(new T(std::forward<Args>(args)...)
{ }
~MyPtr()
{
delete p; // done! who cares what `p` is now.
}
MyPtr(MyPtr const &) = delete;
MyPtr & operator=(MyPtr const &) = delete;
T * operator->() { return p; }
private:
T * p;
}
It would not make anything safer, even if delete assigned NULL to the pointer. Since multiple pointers can point to the same memory address and assigning NULL to one of these will not make others NULL as well.
You can delete a const pointer variable. Setting it to NULL is not possible, Only setting mutable pointer variables to NULL after delete seems somewhat inconsistent.
For one thing, you might want to do pointer arithmetic after delete for efficiency reasons:
const int SIZE = 5;
MyObject* foo[SIZE];
// ... initialize foo with new MyObjects...
for (MyObject* i = &foo[0], end = &foo[0] + SIZE; i < end; ++i)
{
delete i;
}
Related
This question already has answers here:
Is it worth setting pointers to NULL in a destructor?
(12 answers)
Closed 7 years ago.
I saw a common practice of deleting the pointer amd making it null in destructor even if no memory is allocated to pointer on heap. Consider below C++ code:
dummy.h
class dummy
{
int* a;
}
dummy.cpp
dummy::dummy():a(NULL)
{ cout<<Inside Const"; }
dummy::~dummy()
{
if(a!=NULL)
{
delete a;
a = NULL;
}
}
bool func()
{
a = func1();
}
In above code although memory to a is not allocated on heap, even then it is deleted. It should not lead to memory leak?
Making it null is completely pointless, since it's about to be destroyed.
Your code isn't deleting it if it's null, due to the if (a!=NULL). However, that's also pointless: applying delete to a null pointer will simply do nothing, so you can reduce the destructor to an unconditional delete a; (assuming that you know that it's either null, or points to an object created with new).
You do need to make sure your class either isn't copyable, or has valid copy semantics, per the Rule of Three; otherwise, copying the object will lead to deleting the same memory twice, which is not allowed.
Better still, stop juggling pointers, and use smart pointers, containers and other RAII types to make life much simpler.
You should not call delete on a pointer that points to an object that isn't heap allocated object, ever. If you do, the program may ignore that line. Or it may erase your hard drive. Or it may ignore that line on your computer, and after you give the program to a friend it erases their hard drive. Don't do it.
Related: your class is missing the copy constructor, and copy assignment which are critical when you have a pointer that manages memory. Alternatively, replace the int* member with a unique_ptr<int> member, which manages construction and movement for you.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
When should I use the new-operator?
In my example I get the same result using two different methods:
#include <iostream>
int main() {
int *p1;
int n1 = 5;
p1 = &n1;
int *p2;
p2 = new int;
*p2 = 5;
std::cout << *p1 << std::endl;
std::cout << *p2 << std::endl;
return 0;
}
The purpose of using dynamically allocated memory is one (or many) of the following
Run-time control over object's lifetime. E.g. the object is created manually by new and destroyed manually by delete at user's desire.
Run-time control over object's type. E.g. you can deside the actual type of polymorphic object at run-time.
Run-time control over objects' quantity. E.g. you can decide the array size or the number of elements in the list at run-time.
When the object is simply too big to be reasonably placed into any other kind of memory. E.g. a large input-output buffer that is too big to be allocated on stack
In your specific example none of these reasons apply, which means that there's simply no point in using dynamic memory there.
Considering recent C++11 and upcoming C++14 standarts, you should mostly use new operator while programming in languages with garbage collection, such a Java or C#. It is quite natural for these languages. But in modern C++ you can (and mostly always should) avoid allocating memory directly. We have a nice set of smart pointers instead now.
Use new when you want to allocate from the heap, not the stack. Or moving up a level of abstraction. Use new when you need the allocated memory to remain allocated after you the function (more properly scope) in which it is allocated may (in the case of threading) have exited.
You should use new when you wish an object to remain in existence until you delete it. If you do not use new then the object will be destroyed when it goes out of scope.
Some people will say that the use of new decides whether your object is on the heap or the stack, but that is only true of variables declared within functions.
Allocating (and freeing) objects with the use of 'new' is far more expensive than if they are allocated in-place so its use should be restricted to where necessary.
int * p2 = new int;
The new int part tells the program you want some new storage suitable for holding an
operator uses the type to figure out how many bytes are needed.
Then it finds the memory and returns the address. Next, you assign the address to p2, which is
declared to be of type pointer-to-int. Now p2 is the address and *p2 is the value stored
there. Compare this with assigning the address of a variable to a pointer:
int n1;
int * p1 = &n1;
In both cases (p1 and p2), you assign the address of an int to a pointer. In the second
case, you can also access the int by name: p1. In the first case, your only access is via the pointer.
Remember that you should use delete for freeing the memory allocated by new
delete p2;
You need to read some good books ...
I think that "C++ Primer plus" is a good one for you
In this piece of your code you do deal with memory, but with automatic memory. The compiler sorts out for you where to store each variable. you have p1 pointing at n1 but most work was done automatically.
int *p1;
int n1 = 5;
p1 = &n1;ou
However in the next piece of code you request to dynamically allocate an int
int *p2;
p2 = new int;
*p2 = 5;
here you have created a new integer that has been stored dynamically, therefore you should also delete it otherwise you have created your first memory leak. If you allocate dynamically you have to take care you delete it after use.
delete p2;
This is the largest diference when you start to allocate memory using new do delete it otherwise the deconstrucor of an instance of an object will not run and therefore not clear the memory you have allocated.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
How can I overload the new operator for a class type so that it allocates the memory on the stack instead of heap (basically so that the user doesn't have to call delete afterwards).
What about something like this:
class A{
private:
A(int i):
this->i(i);
{}
A a;
int i;
public:
void* operator new(size_t sz){
a(12);
}
};
Would the above solution work?
Don't!
Use automatic storage...
The new operator is designed to implement dynamic allocation (what you are calling "on the heap") and, although you can provide your own allocator, as such you cannot twist it into obeying the scoping rules of objects of automatic storage duration (what you are calling "on the stack").
Instead, write:
MyType myobject; // automatic storage duration
...or smart pointers...
Or, if you don't mind dynamic storage duration but only want to avoid later manual destruction, use smart pointers:
std::unique_ptr<MyType> myptr(new myobject()); // unique, dynamic storage duration
std::shared_ptr<MyType> myptr(new myobject()); // shared, dynamic storage duration
Both of these are found in C++11 (std::) and Boost (boost::).
... or placement new?
Another approach might be placement new but this is a dark and dangerous path to travel that I would certainly not recommend at this stage. Or, frankly, any stage... and you'd usually still need to do manual destruction. All you gain is using the keyword new, which seems pointless.
I think the good answer here is:
Don't overload operator new.
If you still want to go through that road, you can look at this question.
If not, you can always use smart pointers or shared pointers to avoid users having to delete allocated memory.
It seems that you don't know what you're asking. By definition, the new operator allocates memory on the heap. To create an object on the stack, simply declare it as a local variable.
Looking at what you actually want to do, you said that the reason you thought this would be awesome would be:
basically so that the user doesn't have to call delete afterwards
And that functionality is implemented using smart pointers. I highly suggest that you invest your time learning those instead.
Why not just automatic variable (it is "on stack" and does not need to call destructor manually:
int foo() {
A a;
int i;
...
// don't need to call delete
}
To answer your question literally, there is placement new, which takes memory from user - so you can have this memory as automatic buffer:
alignas(int) char buffer[sizeof(int)];
int* p = new (buffer) int;
// ^^^^^^^^
For non POD object - you do not need to call delete - but you must call destructor by hand:
class A { public: ~A(){} };
alignas(A) char buffer[sizeof(At)];
A* p = new (buffer) A;
// ^^^^^^^^
p->~A();
alignas is new in C++11 - in C++03 you must deal with proper alignment somehow differently. Proper aligned memory must be returned from new - otherwise the behavior is undefined.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
I've always done allocations dynamically on the heap; I've done a lot of Objective-C programming as well as plain C and since I'm usually dealing with large chunks of memory, heap objects are necessary to prevent a stack overflow.
I've recently been told that using dynamically allocated objects is discouraged in C++ and that stack objects should be used whenever possible. Why is this?
I guess the best way to illustrate this is by example:
Class *_obj1;
Class *_obj2;
void doThis(Class *obj) {}
void create() {
Class *obj1 = new Class();
Class obj2;
doThis(obj1);
doThis(&obj2);
_obj1 = obj1;
_obj2 = &obj2;
}
int main (int argc, const char * argv[]) {
create();
_obj1->doSomething();
_obj2->doSomething();
return 0;
}
This creates 2 objects, stores them in the pointers, then main() calls a method on each. The Class object creates a char* and stores the C string "Hello!" in it; the ~Class() deallocator frees the memory. The doSomething() method prints out "buff: %s" using printf(). Simple enough. Now let's run it:
Dealloc
Buff: Hello!
Buff: ¯ø_ˇ
Whoa, what happened? C++ deallocated that _obj2 even though we stored a pointer to it; that's because it's on the stack and not the heap, and C++ has no retain count mechanism like Objective-C (I tried implementing one at one point; it worked perfectly but I didn't feel like adding it to everything as a superclass). So we have to jump through hoops to keep it around after the function returns.
Instead of objects, think of "simpler" types. Would you do this:
void create() {
int *obj1 = new int();
int obj2;
_obj1 = obj1;
_obj2 = &obj2;
}
Would you think this would work? Clearly not.
It's very simple. You can't pass out the pointer to an object allocated to the stack (and, as a rule of thumb, you shouldn't pass out the pointer to an object you have just allocated. If someone allocates an object he is responsable to free it)
Heap objects per se are not wrong, failure to manage their lifetime is.
Stack objects have the property that their destructor will be called regardless of how the code leaves the function (exception, return value). Smart pointers exploit this to manage the lifetime of heap allocated objects (a happy medium?)
A basic design principle of C++ is that you don't pay for what you don't use, so that C++ can be used to write highly optimized code. Stack allocation is more efficient, whatever your language.
On Learn C++, they wrote this to free memory:
int *pnValue = new int; // dynamically allocate an integer
*pnValue = 7; // assign 7 to this integer
delete pnValue;
pnValue = 0;
My question is: "Is the last statement needed to free the memory correctly, completly?"
I thought that the pointer *pnValue was still on the stack and new doesn't make any sense to the pointer. And if it is on the stack it will be cleaned up when the application leaves the scope (where the pointer is declared in), isn't it?
It's not necessary, but it's always a good idea to set pointers to NULL (0) when you're done with them. That way if you pass it to a function (which would be a bug), it will likely give you an error rather than trying to operate on invalid memory (makes the bug much easier to track down). And it also makes conditionals simpler.
Setting a pointer to NULL (or zero) after deleting it is not necessary. However it is good practice. For one thing, you won't be able to access some random data if you later dereference the pointer. Additionally, you'll often find code with the following:
if(ptr)
{
delete ptr;
ptr = NULL;
}
So setting the pointer to NULL will ensure it won't be deleted twice.
Finally, you might find code like this:
void foo(bar *ptr)
{
if(!ptr) throw Exception(); // or return, or do some other error checking
// ...
}
And you'd probably want that safety check to be hit.