#include <iostream>
#include <vector>
#include <string>
int main()
{
std::string* p_array = new std::string[10];//Creates 10 elements of String
std::string parr[10];
return 0;
}
The first line does:
I allocated 10 objects of class String from STL library. Now I can separately manipulate every object using member functions of String class. These 10 objects are initialized to Empty string ("").
The second line does:
I allocated 10 objects of class String from STL library and created a pointer to the first object of class String. These 10 objects are initialized to Empty string.
I hope it is correct.
But I don't understand the difference between these 2 definitions / allocations of 10 std::string objects.
Or these 2 lines are identical and it means no difference between them.
p_array declares an array for strings on the heap. You'll need to delete them when you're done to destroy the array and the elements. p_array is just a pointer to the first element of the array.
parr declares an array of strings on the stack. parr is the actuall array. When the function terminates, the array and the strings are destroyed.
You mean that p_array objects I must delete in my code. But parr objects will be deleted by OS.
Am I right? If so, should I allocate string objects using just the second declaration?
What are the advantages to use the first declaration?
#include <iostream>
#include <vector>
#include <string>
int main()
{
{
std::string* p_array = new std::string[10]; // on the free store (heap)
} // oops! memory leak
{
std::string parr[10]; // on the stack
} // no leak
return 0;
}
You need to delete[] p_array; before it goes out of scope or otherwise becomes unreachable.
Here are some (not an exhaustive list...) points about each. First, the array on the free store:
- Has to be explicitly deleted[]
- Is not exception safe
- Can be passed around, cross scope boundaries, etc.
- Is created at run-time and it's size (10) can be a run-time variable
Now, the array on the stack:
- Automatically cleaned up
- Therefore, exception safe
- Is local to the scope
- Must be a compile-time constant size
Let's change this code and now we will use boost::shared_ptr instead of the raw pointer to std::string. I see boost::shared_ptr be the best for this case:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#include <iostream>
#include <vector>
#include <string>
int main()
{
{
shared_ptr<std::string> p_array(new std::string[10]); // on the free store (heap)
//std::string* p_array = new std::string[10]; // on the free store (heap)
} // No any memory leak.
// Is it correct?
{
std::string parr[10]; // on the stack
} // no leak
return 0;
}
1)So now, when we use boost::shared_ptr, the program has no memory leak.
Is it correct?
2)Next: boost::shared_ptr is the best for this case.
Is it correct?
Actually, I'm not sure about this usage. I would guess that the implementation of shared_ptr is specialized for arrays somehow, but I can't confirm without checking some documentation.
The concern is that you have to use delete[] not delete on an array allocated with new[]. For example, std::auto_ptr should never be used with arrays because it calls delete when it goes out of scope.
1)So now, when we use boost::shared_ptr, the program has no memory leak.
Is it correct?
Yes. Actually, a boost::shared_ptr is a "referenced counted" thing so has facilities that you're not using. But yes, in your example, it does delete the array.
2)Next: boost::shared_ptr is the best for this case.
Is it correct?
No. You could use std::auto_ptr or boost::scoped_array.
A vector can be dynamically resized and cleans up after itself. Explicitly reserving the number of elements (10) yields performance very comparable to an array allocated with new.
You mean that p_array objects I must delete in my code. But parr objects will be deleted by OS.
Actually, it's that your compiler will generate code to destroy parr objects once they leave their scope, the OS doesn't do much here. If you don't explicitly call delete on p_array, the memory you have allocated will be deallocated anyways by your OS once the program terminates. Which means that in this simplistic case, you wouldn't really need to delete the array manually. However, manually allocated memory will belong to your program as long as your program is running or until you delete them yourself- this can quite quickly lead to memory problems (not so much with these small practice programs, but in a more realistic situation the memory you can't use anymore due to you not deallocating it properly can quickly reach some troublesome amounts).
Oh and as to the auto_ptr thing: Uh... STL anyone? auto_ptrs don't work with arrays, but STL containers free their occupied memory upon destruction...
If you don't explicitly call delete on p_array, the memory you have allocated will be deallocated anyways by your OS once the program terminates.
Not strictly true. The resources used by the program will be released (mostly). p_array isn't really released, but the OS memory block from which it was suballocated will be released.
If I know (I have only some knowledge of boost library, mostly theoretical), boost::scoped_ptr is just like classic pointer, only safe pointer. I mean it should be used only like a stand-alone pointer, with very limited usage.
Also std::auto_ptr is like obsolete version of boost::scoped_ptr pointers.
If it is wrong, please, correct me.
Not strictly true. The resources used by the program will be released (mostly). p_array isn't really released, but the OS memory block from which it was suballocated will be released.
You mean my example gives some memory leak anyway, don't you? ( You used the word mostly. It means something was not released)