In case you want your project without C++RT dependencies.
In case you want your project without C++RT dependencies.
Then you are looking for the words "safer", "more useful", "recommended" but NOT "better". Something can be better from something else even if there differences are really really small. That is the point of my example.
Think of this. You have a program that uses arrays (a C code). You want to change the arrays so you can do bounding checking. So you, naturally, overload the [] operator. So you don't have to change the code. Only the declaration of the arrays. So you need a container class to do this. So what is better. Do make a container class with a vector or an array with new? Still, with a vector it will be easier, but it will be fairly easy with new. Why have a container that has another object which has new, if you just want to use new?
In this case memory management will be just a delete in the destructor (excect if I am missing something in the whole memory management thing).
Now, If you wanted to resize for any reason, it would be easier just to replace the above with a vector rather than implementing further. But that is a whole different program.
Generally, if you don't need space don't allocate it. If you THINK you don't need space or extra features and they are already built for you then you use them. But that is an if.
I think you might be indeed missing something: vector has the capability to allocate memory but not just yet construct the objects (the excess or reserved memory). Similarly it can destroy the contents but keep the memory in reserve.In this case memory management will be just a delete in the destructor (excect if I am missing something in the whole memory management thing).
If you do new T[x], then the constructor for T is run x times. In fact the vector does something more like this (in reserving):
And then use placement new etc to actually construct the objects when they are placed in the vector.Code:char* p = new char[sizeof(T)*x];
Similarly the destructors must be called separately when instances are removed and then the char array is deallocated.
If you are not aware of these things your own implementation of vector will likely be worse than the standard.
However, how often is the storage allocation an important speed factor? Only if you allocate and deallocate things often, and if it is too slow wouldn't it be better to keep the memory around longer. (In which case you can call vector.clear() to remove the old contents, which might be harder if you just have a dynamically allocated array: delete[] would do the same but you'd also lose the memory which you might want to keep around.)
I might be wrong.
Quoted more than 1000 times (I hope).Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
hmm... but if X is safer than Y, then X is better than Y, with respect to safety. If we change the criteria, or the importance of specific criteria, then an overall judgment of which is generally better may change.Originally Posted by C_ntua
If the aim is merely to perform bounds checking on a dynamic array, then you would save on designing and implementing a container simply by using the at() member function of std::vector, at the cost of having to make more changes to the original code. If a checked standard container implementation is available, you could simply use overloaded operator[] of std::vector.Originally Posted by C_ntua
Consider that you would likely want to replace malloc(), realloc() and free(), in which case you may end up duplicating the interface and implementation of std::vector, so simply substituting for std::vector may be a better option than implementing your own container, especially since the implementation of std::vector is likely to be well tested.
Other than these considerations, I do not see anything wrong with implementing RAII yourself with new[] and delete[]. (You may want to use ::operator new and ::operator delete with placement new, depending on your requirements. Read Allocating Arrays with Placement new.)
Last edited by laserlight; 10-02-2008 at 06:18 AM.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Just for fun: the C++ STL containers allow one to provide their own allocators; using a vendor provided general purpose 'new'/'delete' may require more total extra bytes per instance than 'std::vector<?>' with a custom purpose allocator.Do make a container class with a vector or an array with new?
Soma
Well, I agree that better isn't defined. Depends on how you mean it. But since somebody asked to tell ONE case of being better, then that one case might be memory. And in any case, if in my example X is 3 or 4 then the extra memory used from vector is probably bigger than the data. That by itself is kind of bad.
As for replacing malloc(), realloc(), free() in my imaginary code, I agreed that if you have something more complicated than allocating memory and freeing at the end then a vector might (or probably) will be better.
But even still. It is a C code. The memory might be actually limited. You might want to use C++ just because of the overloading of operator[] which is something C doesn't have. In this case a vector would be wrong, not just worst. Since the user may enter something small as a size (like 3 or 4).
My point is that a vector has a disadvantage. Size. If better = size then new is much better than a vector.
As for the :perator new/delete... interesting. You learn something new every day.
In that case, the correct solution is to use std::tr1::array, which also has at() member functions that do bounds checking. If a TR1 implementation is unavailable, then you would implement something like it (without using dynamic memory allocation, of course).Originally Posted by C_ntua
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
No, but there may be a problem: since std::tr1::array is a fixed size array, if the size is determined by the user at run time, then it will not be appropriate. Back to the question of space overhead for std::vector...Originally Posted by C_ntua
It depends on the type of the data. If the type is a 4 byte int, then 3 or 4 of them would take up 12 or 16 bytes. If size_t and int* are also 4 bytes, then a vector only needs 12 bytes (8 for the variables to track size and capacity, and another 4 for the pointer).Originally Posted by C_ntua
But to put this in context, a dynamic array-like container that cannot expand needs 8 bytes (4 for the variable to track size, and 4 for the pointer). Under my assumptions of sizeof(size_t) and sizeof(int*), this means that we are comparing 24 or 28 bytes with 20 or 24 bytes, which is not a very big deal, especially since the numbers involved are small to begin with (and they would be roughly halved if we stored 3 or 4 chars instead). It might become a big deal if we have a huge non-rectangular array/vector of them, in which case such a container might really make things easier, if space consumption was a problem.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
>> Then you are looking for the words "safer", "more useful", "recommended" but NOT "better". <<
If you can find a definition of better that would apply to new[] over vector, I'd happily accept it. I can think of only one at the moment: your instructor doesn't allow you to use vector on your assignment. In that case new[] would be better.
>> Something can be better from something else even if there differences are really really small. That is the point of my example. <<
But in your example, the vector was better because of the automatic memory management. You can't just pick and choose what factors to talk about. Overall, vector is better in your example.
>> But since somebody asked to tell ONE case of being better, then that one case might be memory. <<
I apologize if I wasn't clear. I wasn't looking for one advantage of new[] over vector. I was looking for one programming situation (as a relatively complete situation) where new[] was better for the overall program. Your example specifies an advantage of new[] over vector (a savings of a few bytes). My point is that minor advantage is outweighed by other disadvantages in real situations.
>> In this case memory management will be just a delete in the destructor (excect if I am missing something in the whole memory management thing). <<
Unfortunately, you are missing something (that is more important than what anon noticed). If you use vector, you don't need to write the destructor. If you use new[], you need to write the destructor and either write or disable the copy constructor and copy assignment operator. That's something people often forget when using new[] (another reason vector is better). If you fail to do that, your code crashes (or worse) if that object ever gets copied.
>> Generally, if you don't need space don't allocate it. <<
If an insignificant amount of space will make the rest of your program safer and easier to write and maintain, then yes, you absolutely should allocate it.
C_ntua, the entire point of the original comment was that you should understand what vector is and what it does. If you're using new[]/delete[] in your program, there is a very good chance that you would benefit from using vector instead. In my experience coding and answering questions on these forums, I have never heard of an actual situation where the vector was not a better choice than new[]/delete[], so if you want to make the best possible program, you should consider using vector. Of course there are many situations where new[]/delete[] works just fine, and if it is already written that way then this doesn't mean you have to change it. But if you're writing new code or learning the language, then taking the time to understand this "better" alternative is worth the investment IMO.