Hi,
Is this allowed?
Because shouldn't this be deleted by delete [] and auto_ptr does not support this?Code:auto_ptr<char> a( new char[10] );
Hi,
Is this allowed?
Because shouldn't this be deleted by delete [] and auto_ptr does not support this?Code:auto_ptr<char> a( new char[10] );
No, it's not allowed.
If you want automatic management of your array, use a std::vector. If that's really not what you want, look at the Boost libraries. Their smart pointer library has scoped_array and shared_array, which may fit your needs.
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
won't this do?
Code:class ScopeArray { char* p; public: ScopeArray(char* _p):p(_p) {} ~ScopeArray() { free(p); } };
That's basically what scoped_array is, yes. Except for the free, which has absolutely no business being there! The memory was allocated with new[]. It must be freed with delete[].
Of course, then there's pointer access, validation of non-deletion of incomplete type, indexing and dereference operator overloads, resetting, preventing copying, debug assertions for not dereferencing null pointers ... I think that's all that scoped_array does.
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
§"(/% programming classes!
OK, from memory. But remember: A std::vector is preferable.
I have to say it again: A std::vector is preferable.Code:template <typename T> void checked_array_delete(T *p) { void( sizeof(T) ); // ensure type is fully defined delete [] p; // because if it isn't, this will compile but give undefined behaviour } template <typename T> class scoped_array { T *m_ptr; // Prevent copying. scoped_array(const scoped_array &o); scoped_array &operator =(const scoped_array &o); public: explicit scoped_array(T *p = 0) m_ptr(p) { } ~scoped_array() { reset(); } T *get() { return m_ptr; } T &operator *() { assert(m_ptr); return *get(); } T &operator [](std::size_t idx) { assert(m_ptr); return get()[idx]; } void reset(T *p = 0) { checked_delete(m_ptr); m_ptr = p; } };
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
Why not? According to the Boost FAQ:I am not allowed in work to use boost .
"The Boost license permits the creation of derivative works for commercial or non-commercial use with no legal requirement to release your source code."
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Beautiful, Thanks CornedBee.
When you say vector do you mean create a wrapper for the vector?
one that will be able to do something like that:
or maybe it is possible with stl algorithms, and you meant that?Code:VectorWrapper vw strcpy( vw, str);
Last edited by kroiz; 11-22-2007 at 05:56 AM.
It is not a license issue, I am not sure ( and it is hard getting an answer, The one with the answer is a busy man with little patience ) but I think that it has to do with trouble building boost on other platforms with the compilers we have.
I have been asking for boost for a long time.
My guess is that it is possible in any case but just too much work.
Last edited by kroiz; 11-22-2007 at 06:01 AM.
No, I mean a simple vector, as it is.
You can use strcpy with a vector like this:
Or like this:Code:std::vector<char> v(strlen(str) + 1); strcpy(&v[0], str);
That should be the fastest code if your vector implementation is properly optimized for primitives. Alternatively, how about this?Code:std::vector<char> v(str, str + strlen(str) + 1);
Or yes, even with STL algorithms.Code:size_t slen = strlen(str) + 1; std::vector<char> v(slen); memcpy(&v[0], str, slen);
or (faster):Code:std::vector<char> v; std::copy(str, str + strlen(str) + 1, std::back_inserter(v));
GCC's STL optimizes this to a single memmove. (A tiny bit slower than memcpy.)Code:size_t slen = strlen(str) + 1; std::vector<char> v(slen); std::copy(str, str + slen, v.begin());
Or you could use a proper std::string.
Code:std::string s(str);
You must work on some obscure platforms. Boost is quite portable, really. OK, not all libraries, and there are some compilers that have serious problems, but generally, why not at least identify some "safe" Boost libraries? Not being allowed to use Boost's smart pointers is absurd.
Alternatively, perhaps, the C++ Technical Report 1 also includes the smart pointers. This document encourages vendors to supply components within the namespace std::tr1. GCC 4.1 and VC++.Net 2005 both provide the smart pointers, I think. For other compilers, other implementations could be found.
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
Thanks again, this is realy beautiful.
It did not occure to me that since vector uses continues memory I can pass it to functions that has the form of
Is string continues in memory too?Code:something f(char* output, int outputLen);
We do, I only build on those platforms I do not however create the makefiles and all that libraries and dependacies. so I dont know much about the obstackles there.You must work on some obscure platforms.
Building on windows and linux is easy compared to those.
I guess they dont understand how much it cost them to let us develop in such a crippled environment.
You can use the c_str() member function of std::string to obtain a const char*. There is no way to get mutating access to the string.
By the way, forgot boolean conversion in my quick scoped_array. These members:
The weird boolean conversion is chosen so that use in boolean contexts is possible, but unintended conversions to integers are not.Code:typedef T* (scoped_array::*safe_bool)(); operator safe_bool() { return get() ? &scoped_array::get : 0; } bool operator !() { return !get(); }
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
You could make your own, crude smart pointer. It doesn't take a lot of work. It doesn't need to be perfect or full of functionality - just... work.
Sorry, if someone is reinventing a wheel you suggest reinventing a square wheel? ;P
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.
If you can't use a wheel but you need one, then why not use your own crude wheel (that you can use)?