fully deallocating the memory of a std::vector container - c++

From the vector docs it would appear that the proper way to completely deallocate a vector of values to which you have a class member pointer such as:
std::vector<MyObject>* mvMyObjectVector_ptr;
...
//In the class constructor:
mvMyObjectVector_ptr = new std::vector<MyObject>();
would be to invoke the following, in order, in the class's destructor implementation
mvMyObjectVector_ptr->clear();
delete mvMyObjectVector_ptr;
However, this appears to be leading to SIGABRT 'pointer being freed was not allocated' errors. Is the above idiom the correct way to completely deallocate the memory held at the address pointed to by a pointer to a vector (if it is, I assume my errors are coming from something else)? If not, what is the correct way?

Yes, it is correct, provided mvMyObjectVector_ptr has been allocated using new.
Additionally, MyObject needs to satisfy certain requirements before it can be used with std::vector.
The call to clear() is redundant and can be omitted.
Some likely reasons for the SIGABRT include:
mvMyObjectVector_ptr hasn't been allocated using new;
MyObject violates the Rule of Three;
the class the contains the vector violates the Rule of Three.

I don' think your problem lies in the code you have shown us.
This line:
//In the class constructor:
suggests you are using this inside a class and not implementing the rule of three correctly.
A better idea is not to use a pointer to a vector.
Just declare it as a normal automatic member.
class MyClassContainingVector
{
public:
std::vector<MyObject> mvMyObjectVector;
// ^^^^^ notice no pointer.
};
Now it will be created and destroyed correctly and automatically.
Neither your constructor or destructor will need any code to manage this object.

Yes, dynamically allocating a std::vector object by calling new and invoking its destruction by calling delete will result in memory that has been internally used for holding its elements being freed.
However it would be much simpler and more reliable to follow RAII idiom and use an object with automatic storage duration:
{
std::vector<MyObject> myVector;
...
} // <-- memory is freed here
when execution leaves this scope (note that it could be also caused by exception being thrown etc.), it is guaranteed that myVector object will be destructed and memory will be freed.

Vectors usually shouldn't be held as dynamically allocated pointers. They should be just member variables of your class, in most situations (though there are always exceptions). If they are pointers allocated by 'new', and simple 'delete' should work.
Vectors handle memory allocation for you, so you don't have to. However, if you want to truly free all the storage memory held in a vector, even if it's on the stack, there's a new function for that.
Because vector.reserve() only expands memory, but never shrinks it, in C++11, a new function was added for the purpose of freeing the reserved memory: vector.shrink_to_fit(). Implementations and free to do what they want with it, but you're basically asking the implementation to free the memory, so they should answer the request in a reasonable way.
You can truly clear a vector by going like this:
vector.clear(); //Erases the elements.
vector.shrink_to_fit(); //Erases the memory no longer needed by the elements.
The reasons why vectors hold onto their memory is for performance reasons, so you should only do this if you actually understand why they have memory in reserve, and are willing to deal with (or know you won't have to deal with) any performance hits that result from micro-managing the memory.

Related

Proper way to delete and free up memory of a vector (prevent different memory related errors) in c++

creating a vector:
std::vector<int> pqrs;
delete in proper way to free up all memory (prevent memory leaks and other memory related issues) inside the function:
pqrs.clear();
std::vector<int>().swap(pqrs);
My question is: both clear and swap required (say for calling destructor)? or swap is sufficient for all purpose.
In case of std::vector<int> you don't need to do either clear() nor swap to free memory, because elements of std::vector<int> here (ints) are automtically allocated and freed by the std::vector<int> methods anddestructor. Data will be freed at the end of scope (function or program).
Hence,answer to your question would be, You don't need to call clear or swap.
Since vector<int> object in above question is a variable with automatic storage - so it will be automatically destroyed when it goes out of scope. And when a container object goes out of scope, it's destructor is called which in-turn frees up space used for storage of contained elements and during this step destructor for all contained elements also gets invoked (in case of user-defined types). So, if we have just plan int elements, no need to do anything extra. But we would have memory leak if contained type if T* where T is some user-defined type because in that case destructor wouldn't be called explicitly for pointed-to objects.
Your phrase about memory leaks makes the whole meaning of the question unclear. When the vector goes out of scope, the memory is released. There should be no memory leak.
In major projects, it is fairly common to need a vector to release its allocation at a certain point before it goes out of scope. Failure to do so is not a memory leak but may be a problem. For that purpose, .clear() is useless. The swap approach you suggested (without the .clear) works. I don't know a way to do it without swap.

Should I apply RAII to all arrays I allocated?

I'm studying C++ now. It is a so complicated language that I'm not sure which feature I should use and when to use.
C++ Primer introduces RAII as a method to ensure exception safety. Does that mean, as a good behavior, when I want to use an array, I should put array into an class to allocate and destroy resources. I know my idea is very simple, or naive.
I'm just curious about what is good C++ coding behavior.
RAII means that a resource is tied to the object lifetime.
Every STL class of C++ follows this principle, this means that if you need an array you can simply use std::vector.
The destructor of the vector class will take care of deleting the resources when your instance goes out of the scope.
This means that in your case, instead of using new like this:
int *array = new int[n];
you should use:
vector<int> array(n);
If you really need to allocate on the heap to have a shared pointer and still be safe by using RAII you can do (requires C++11):
shared_ptr<vector<int>> array(new vector<int>(10));
It depends how you create your array. If you create it in some block of code like this
int arr[5];
it has automatic storage. This array is automatically destroyed when it goes out of scope.
The only time you have to explicitly manage the lifetime of your objects is if you dynamically allocate them, perhaps like so:
int* arr = new int[5];
This allocates an array of 5 ints which need to be manually deleted later like this:
delete[] arr;
RAII is the idea that we can have a class's constructor perform the dynamic allocation and its destructor perform the deallocation. Then if we create objects of this class type, they will internally perform dynamic allocation, but we can be sure that the memory will be correctly deallocated when finished with.
So yes, if you really want a dynamically allocated array, you could encapsulate it in your own class. However, this already exists in a more powerful form: std::vector. The std::vector type internally manages a dynamically allocated array, but also allows you to add elements to and remove elements from it at run-time.
Note that this isn't something specific to arrays. Best practice is to encapsulate all dynamic allocation (even a simple new int) within classes. The standard library provides many classes to help you do this (in particular, smart pointers).
RAII is a recommended idiom for resource management -- resources can be threads, memory... I frequently encounter long-time developers who don't understand RAII or how to use it, so there's no shame in asking. Unfortunately, I think you need a little background and terminology to understand it. In C++ you can create objects in one of two kinds of memory: The stack and the heap.
The Stack:
Consider this code:
class Foo
{
// some implementation
}
void bar()
{
Foo f;
// do something with f.
// maybe it throws an exception, maybe not.
}
Here the object f of type Foo has been created on the stack. When the running program leaves the scope in which f was created (in our example when it leaves the function bar()), f's destructor will called, regardless of how it leaves the scope. It might leave scope because the function executed successfully, or it might leave scope because an exception was thrown.
Heap allocation
Now consider the following:
class Foo
{
// same thing
}
void bar()
{
Foo* f = new f;
// whatever
delete f;
}
In this case we created the object f on the heap. You can tell we did so because we called the new operator. Whenever an object is created with new, we have to call delete in order to free the memory up. This can be error prone, because people forget to call delete, or they return the pointer and it's unclear where the pointer should get deleted, or because an exception is thrown. RAII is a solution to all those, and it should be your first tool of choice.
But that doesn't mean you should put your arrays in a class (well it kind of does in some circumstances, but probably not in the way that you mean). Consider the following:
void foo()
{
// c-style array, but fixed size.
int bar_stack[5];
// c-style array, dynamically allocated!
unsigned int array_size = get_array_size();
int* bar_heap = new int[array_size]
// c++ way:
std::vector bar_vector(array_size);
}
In the first example we have a fixed c-style array, it's allocated on the stack, so it's nothing to worry about. In the second case, it's dynamically allocated (the compiler doesn't know the size, its available at run time), so we would need a delete, meaning we'd need to protect against exceptions and make sure there's a clear owner. In the third case we just use a vector, which is a standard container.
Now I provided all that because I was afraid you wouldn't understand the short answer which is: Yes you should generally use RAII to manage your resources, but you should use std containers, not arrays. Why? Because std containers provide RAII for you -- unless you make a container of pointers, or allocate your vector on the heap.
I hope that helps.

How best to allocate dynamic memory in c++

which is better for memory allocation in c++ for classes and template. malloc() or new; can malloc() be used to allocate memory for classes or template?
It is possible to do this, although not the way you do it, and in any case it's not really beginner stuff. The reason your approach does not work is that an uninitialized slab of memory is not the same as a valid object. But before I continue:
IMPORTANT STYLE NOTE: I am going to leave aside for the sake of brevity the usual memory management mechanics (smart pointers et al) that you should stick to religiously as a beginner (and, in fact, as an expert, but they don't need to be told). Do not use code like what I'm about to show here in production (not without all the necessary bookkeeping around it), or things will break in ways that are horrible to debug. I'm only doing it because doing it properly would obscure the mechanics I'll try to show.
The difference between a slab of uninitialized memory and a valid object are, in a broad sense, class invariants. What this means is that a class defines certain properties for its objects that these always fulfill. For example, a string class will generally guarantee that the pointer to its data will not be a dangling pointer, and that its size will not reported to be larger than the block of memory that pointer points to. An uninitialized slab of memory cannot guarantee either of those things, and that is why we have constructors. A constructor is a function that constructs an object into an uninitialized slab of memory, fixing these invariants, and most of the time it is called for you automatically. If you write
Foo f;
memory is obtained from the stack (simplified terminology; please bear with me, language lawyers), and the default constructor Foo::Foo() is called on that piece of memory. Similarly, if you write
Foo *p = new Foo();
operator new obtains memory from the heap and calls the constructor on that piece of memory. Possibly it does more than that, but let's leave that possibility aside for now.
So what goes wrong in your code? Well, when you write
*obj = A();
this is an assignment. It assumes that there is a valid object *obj that a newly constructed object can be copied into. This is not the case, because obj points to an uninitialized slab of memory.
So, before you can use your uninitialized slab of memory like an object, you have to construct one into it. This is possible, and it is called placement new. The syntax looks like this:
new(obj) A();
And later you have to call the destructor (the constructor's counterpart; its purpose is to undo what the constructor did) manually like so:
obj->~A();
...after which obj will again point to uninitialized memory, and (unless the class is buggy) all necessary cleanup has been done. Except giving back the slab of memory, because that was allocated outside the constructor/destructor duo. Normally it would happen automatically at the end of the scope (for automatic variables like f above) or delete would do it for you (for dynamic storage objects like *p above), but since you did the allocation yourself, you have to do the deallocation yourself.
The use of malloc() for allocatiog C++ objects shall be avoided.
Rewrite your main() using C++ practice:
A *obj = new A(); // get memory and initialize the object
B<int> *objb = new B<int>(); // same
This works better and is easier to read !
Remark: Statements like *obj=A(); may call a class specific assignment operator, which would assume that *obj was already initialized by a constructor and is in a valid state. If memory was simply aquired by malloc(), this assumption is not fulfilled.

dynamic object creation in vector

so i would like to have vector<OtherClassName> theVector as a member of a BaseClass
i am wondering in many ways that i can get a memory leaks...
will doing this results in memory leaks?
BaseClass::someFunction(){
OtherClassName * c = new OtherClassName();
theVector.push_back((*c));
}
i'm a beginner in C++, learning from the internet.
will doing this result in memory leaks?
Yes, this will result in a memory leak. Every object allocated with new must be destroyed with delete. Failing to do so causes a memory leak.
In particular, what you are storing in your vector here is a copy of the object allocated with new. If you want your container to hold objects of a certain class, it is enough to do:
BaseClass::someFunction()
{
OtherClassName c;
theVector.push_back(c);
}
Notice that the vector, like all containers of the C++ Standard library, has value semantics: this means that what you are inserting in the vector is a copy of the object you pass to push_back(). Further modifications to the original objects won't be reflected by the state of the object contained in the vector, and vice versa.
If you want this to happen, i.e. if you need reference semantics, you will have to let your vector contain (possibly smart) pointers. For instance:
#include <memory>
// theVector would be declared as:
// std::vector<std::shared_ptr<OtherClassName>> theVector;
BaseClass::someFunction()
{
std::shared_ptr<OtherClassName> pC = std::make_shared<OtherClassName>();
theVector.push_back(pC);
}
Manual memory management through new and delete is considered bad programming practice in Modern C++, because it easily leads to memory leaks or undefined behavior, and negatively affects the design of your program in terms of robustness, readability, and ease of maintenance.
Classes that dynamically create anything should have a destructor that will free the memory when the object is destroyed. If you don't have one you have memory leaks. Any memory taken by a new statement must have a corresponding delete statement or you will have a memory leak. As your class is written now it will have memory leaks since you never free the memory again. Your destructor should simply go through the vector and free the memory from every pointer it stores.

When should I use the new keyword in C++?

I've been using C++ for a short while, and I've been wondering about the new keyword. Simply, should I be using it, or not?
With the new keyword...
MyClass* myClass = new MyClass();
myClass->MyField = "Hello world!";
Without the new keyword...
MyClass myClass;
myClass.MyField = "Hello world!";
From an implementation perspective, they don't seem that different (but I'm sure they are)... However, my primary language is C#, and of course the 1st method is what I'm used to.
The difficulty seems to be that method 1 is harder to use with the std C++ classes.
Which method should I use?
Update 1:
I recently used the new keyword for heap memory (or free store) for a large array which was going out of scope (i.e. being returned from a function). Where before I was using the stack, which caused half of the elements to be corrupt outside of scope, switching to heap usage ensured that the elements were intact. Yay!
Update 2:
A friend of mine recently told me there's a simple rule for using the new keyword; every time you type new, type delete.
Foobar *foobar = new Foobar();
delete foobar; // TODO: Move this to the right place.
This helps to prevent memory leaks, as you always have to put the delete somewhere (i.e. when you cut and paste it to either a destructor or otherwise).
Method 1 (using new)
Allocates memory for the object on the free store (This is frequently the same thing as the heap)
Requires you to explicitly delete your object later. (If you don't delete it, you could create a memory leak)
Memory stays allocated until you delete it. (i.e. you could return an object that you created using new)
The example in the question will leak memory unless the pointer is deleted; and it should always be deleted, regardless of which control path is taken, or if exceptions are thrown.
Method 2 (not using new)
Allocates memory for the object on the stack (where all local variables go) There is generally less memory available for the stack; if you allocate too many objects, you risk stack overflow.
You won't need to delete it later.
Memory is no longer allocated when it goes out of scope. (i.e. you shouldn't return a pointer to an object on the stack)
As far as which one to use; you choose the method that works best for you, given the above constraints.
Some easy cases:
If you don't want to worry about calling delete, (and the potential to cause memory leaks) you shouldn't use new.
If you'd like to return a pointer to your object from a function, you must use new
There is an important difference between the two.
Everything not allocated with new behaves much like value types in C# (and people often say that those objects are allocated on the stack, which is probably the most common/obvious case, but not always true). More precisely, objects allocated without using new have automatic storage duration
Everything allocated with new is allocated on the heap, and a pointer to it is returned, exactly like reference types in C#.
Anything allocated on the stack has to have a constant size, determined at compile-time (the compiler has to set the stack pointer correctly, or if the object is a member of another class, it has to adjust the size of that other class). That's why arrays in C# are reference types. They have to be, because with reference types, we can decide at runtime how much memory to ask for. And the same applies here. Only arrays with constant size (a size that can be determined at compile-time) can be allocated with automatic storage duration (on the stack). Dynamically sized arrays have to be allocated on the heap, by calling new.
(And that's where any similarity to C# stops)
Now, anything allocated on the stack has "automatic" storage duration (you can actually declare a variable as auto, but this is the default if no other storage type is specified so the keyword isn't really used in practice, but this is where it comes from)
Automatic storage duration means exactly what it sounds like, the duration of the variable is handled automatically. By contrast, anything allocated on the heap has to be manually deleted by you.
Here's an example:
void foo() {
bar b;
bar* b2 = new bar();
}
This function creates three values worth considering:
On line 1, it declares a variable b of type bar on the stack (automatic duration).
On line 2, it declares a bar pointer b2 on the stack (automatic duration), and calls new, allocating a bar object on the heap. (dynamic duration)
When the function returns, the following will happen:
First, b2 goes out of scope (order of destruction is always opposite of order of construction). But b2 is just a pointer, so nothing happens, the memory it occupies is simply freed. And importantly, the memory it points to (the bar instance on the heap) is NOT touched. Only the pointer is freed, because only the pointer had automatic duration.
Second, b goes out of scope, so since it has automatic duration, its destructor is called, and the memory is freed.
And the barinstance on the heap? It's probably still there. No one bothered to delete it, so we've leaked memory.
From this example, we can see that anything with automatic duration is guaranteed to have its destructor called when it goes out of scope. That's useful. But anything allocated on the heap lasts as long as we need it to, and can be dynamically sized, as in the case of arrays. That is also useful. We can use that to manage our memory allocations. What if the Foo class allocated some memory on the heap in its constructor, and deleted that memory in its destructor. Then we could get the best of both worlds, safe memory allocations that are guaranteed to be freed again, but without the limitations of forcing everything to be on the stack.
And that is pretty much exactly how most C++ code works.
Look at the standard library's std::vector for example. That is typically allocated on the stack, but can be dynamically sized and resized. And it does this by internally allocating memory on the heap as necessary. The user of the class never sees this, so there's no chance of leaking memory, or forgetting to clean up what you allocated.
This principle is called RAII (Resource Acquisition is Initialization), and it can be extended to any resource that must be acquired and released. (network sockets, files, database connections, synchronization locks). All of them can be acquired in the constructor, and released in the destructor, so you're guaranteed that all resources you acquire will get freed again.
As a general rule, never use new/delete directly from your high level code. Always wrap it in a class that can manage the memory for you, and which will ensure it gets freed again. (Yes, there may be exceptions to this rule. In particular, smart pointers require you to call new directly, and pass the pointer to its constructor, which then takes over and ensures delete is called correctly. But this is still a very important rule of thumb)
The short answer is: if you're a beginner in C++, you should never be using new or delete yourself.
Instead, you should use smart pointers such as std::unique_ptr and std::make_unique (or less often, std::shared_ptr and std::make_shared). That way, you don't have to worry nearly as much about memory leaks. And even if you're more advanced, best practice would usually be to encapsulate the custom way you're using new and delete into a small class (such as a custom smart pointer) that is dedicated just to object lifecycle issues.
Of course, behind the scenes, these smart pointers are still performing dynamic allocation and deallocation, so code using them would still have the associated runtime overhead. Other answers here have covered these issues, and how to make design decisions on when to use smart pointers versus just creating objects on the stack or incorporating them as direct members of an object, well enough that I won't repeat them. But my executive summary would be: don't use smart pointers or dynamic allocation until something forces you to.
Which method should I use?
This is almost never determined by your typing preferences but by the context. If you need to keep the object across a few stacks or if it's too heavy for the stack you allocate it on the free store. Also, since you are allocating an object, you are also responsible for releasing the memory. Lookup the delete operator.
To ease the burden of using free-store management people have invented stuff like auto_ptr and unique_ptr. I strongly recommend you take a look at these. They might even be of help to your typing issues ;-)
If you are writing in C++ you are probably writing for performance. Using new and the free store is much slower than using the stack (especially when using threads) so only use it when you need it.
As others have said, you need new when your object needs to live outside the function or object scope, the object is really large or when you don't know the size of an array at compile time.
Also, try to avoid ever using delete. Wrap your new into a smart pointer instead. Let the smart pointer call delete for you.
There are some cases where a smart pointer isn't smart. Never store std::auto_ptr<> inside a STL container. It will delete the pointer too soon because of copy operations inside the container. Another case is when you have a really large STL container of pointers to objects. boost::shared_ptr<> will have a ton of speed overhead as it bumps the reference counts up and down. The better way to go in that case is to put the STL container into another object and give that object a destructor that will call delete on every pointer in the container.
Without the new keyword you're storing that on call stack. Storing excessively large variables on stack will lead to stack overflow.
If your variable is used only within the context of a single function, you're better off using a stack variable, i.e., Option 2. As others have said, you do not have to manage the lifetime of stack variables - they are constructed and destructed automatically. Also, allocating/deallocating a variable on the heap is slow by comparison. If your function is called often enough, you'll see a tremendous performance improvement if use stack variables versus heap variables.
That said, there are a couple of obvious instances where stack variables are insufficient.
If the stack variable has a large memory footprint, then you run the risk of overflowing the stack. By default, the stack size of each thread is 1 MB on Windows. It is unlikely that you'll create a stack variable that is 1 MB in size, but you have to keep in mind that stack utilization is cumulative. If your function calls a function which calls another function which calls another function which..., the stack variables in all of these functions take up space on the same stack. Recursive functions can run into this problem quickly, depending on how deep the recursion is. If this is a problem, you can increase the size of the stack (not recommended) or allocate the variable on the heap using the new operator (recommended).
The other, more likely condition is that your variable needs to "live" beyond the scope of your function. In this case, you'd allocate the variable on the heap so that it can be reached outside the scope of any given function.
The simple answer is yes - new() creates an object on the heap (with the unfortunate side effect that you have to manage its lifetime (by explicitly calling delete on it), whereas the second form creates an object in the stack in the current scope and that object will be destroyed when it goes out of scope.
Are you passing myClass out of a function, or expecting it to exist outside that function? As some others said, it is all about scope when you aren't allocating on the heap. When you leave the function, it goes away (eventually). One of the classic mistakes made by beginners is the attempt to create a local object of some class in a function and return it without allocating it on the heap. I can remember debugging this kind of thing back in my earlier days doing c++.
C++ Core Guidelines R.11: Avoid using new and delete explicitly.
Things have changed significantly since most answers to this question were written. Specifically, C++ has evolved as a language, and the standard library is now richer. Why does this matter? Because of a combination of two factors:
Using new and delete is potentially dangerous: Memory might leak if you don't keep a very strong discipline of delete'ing everything you've allocated when it's no longer used; and never deleteing what's not currently allocated.
The standard library now offers smart pointers which encapsulate the new and delete calls, so that you don't have to take care of managing allocations on the free store/heap yourself. So do other containers, in the standard library and elsewhere.
This has evolved into one of the C++ community's "core guidelines" for writing better C++ code, as the linked document shows. Of course, there exceptions to this rule: Somebody needs to write those encapsulating classes which do use new and delete; but that someone is rarely yourself.
Adding to #DanielSchepler's valid answer:
The second method creates the instance on the stack, along with such things as something declared int and the list of parameters that are passed into the function.
The first method makes room for a pointer on the stack, which you've set to the location in memory where a new MyClass has been allocated on the heap - or free store.
The first method also requires that you delete what you create with new, whereas in the second method, the class is automatically destructed and freed when it falls out of scope (the next closing brace, usually).
The short answer is yes the "new" keyword is incredibly important as when you use it the object data is stored on the heap as opposed to the stack, which is most important!