A smart pointer is used in this small routine to spare the caller the hassle of free()ing the returned buffer (and protect against his failure to do so) :
char* toupper(const string& s){ string ret(s.size(), char()); for(unsigned int i = 0; i < s.size(); ++i) ret[i] = (s[i] <= 'z' && s[i] >= 'a') ? s[i]-('a'-'A') : s[i]; return (char*) memcpy( chkedAlloc(1+ret.size(),*std::make_shared<char*>(nullptr)), ret.c_str(), 1+ret.size() ); } chkedAlloc(n,A) returns new A[n] after catching std::bad_allocs.
This looks like a textbook use of smart pointers to make life easier & safer?
Do you see any fault with/possible improvement in this code?
improvements/comments:
- Return a string. It's destructor frees the associated storage when it goes out of scope.
- This is a case of "shared_ptr as a last resort". "shared" is more expensive than "unique".
- If you're thinking that :
- a shared_ptr is thread-safe
- a unique_ptr can't be passed to others
stop believing that. Owners can deal unique_ptrs, but one at a time can hold ownership.
- Consider the standard template algo std::transform.
- Don't use use
std::stringin your example code, preferint, to avoid all kinds of side-discussions.
unique_ptr<char*> toupper(const string& s){ string ret(s.size(), char()); for(unsigned int i = 0; i < s.size(); ++i) ret[i] = (s[i] <= 'z' && s[i] >= 'a') ? s[i]-('a'-'A') : s[i]; char *p = new char[1+ret.size()]; // try/catch(std::bad_alloc) return make_unique<char*>((char*) memcpy(p, ret.c_str(), 1+ret.size())); } void f() { string s = "hello"; .. { char* p = *toupper(s); // this scope now owns the pointer } // leaving the scope: allocated memory on the heap freed by smart pointer .. }
std::string.chkedAlloc? That return statement is undecipherable to me. And I see a lot of code in a day. I can't think of any way*std::make_shared<char*>(nullptr)can do anything helpful.make_shared()in this code makes no sense. It is allocating an ownedchar*pointer (not achar[]buffer!) that doesn't point anywhere.memcpy()needs allocated memory to copy to. What doeschkedAlloc()actually do? This looks like very dangerous code to me. Especially since you mentionfree(), whichshared_ptrdoes not use, but doeschkedAlloc()really require it?std::unique_ptris perfectly fine,std::shared_ptrhas some unexpected overhead involved (due to its thread safety obligations)