For example:
size_t len; // will be filled in by createString
char * p = createString(&len); // a function that returns a char
array, caller gets ownership
std::string theString(p, len); // how to create this string without
making a copy?
Best regards,
Francis
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
> How can I construct a string using a char pointer without making a
> copy, but simply by taking ownership of it?
You can't. How would std::string even know how to release the space you
give it?
If you need something to take ownership of a C string, you could always
do something like:
struct shared_c_string
{
shared_c_string(char* s = 0) : ptr(s, free) {}
operator const char*() const { return ptr.get(); }
private:
boost::shared_ptr<char> ptr;
};
--
Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> 773 961-1620
What does "gets ownership" mean? Presumably the caller is responsible
for disposing of the memory, the question is "how?". Likely answers
include:
free(p)
CoTaskMemFree(p) (MS Windows specific)
(lots of other platform and library specific calls)
I suppose it is possible it might even be:
delete [] p;
(although in that case, one has to ask why the API didn't return a
std::string or std::vector<char> in the first place.)
There is no way to do (exactly) what you want. Sorry.
Doesn't std::string just need to call 'free'?
Kind regards,
Francis
--
--
(snip)
> size_t len; // will be filled in by createString
> char * p = createString(&len); // a function that returns a char
> array, caller gets ownership
> std::string theString(p, len); // how to create this string without
> making a copy?
The closest you can get to what you want is by making use of the
placement new operator as given in the program below. Also check out
the FAQ on placement new at
http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10
$ cat place.cc
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
char * createString(int len) {
char *dlg = new char[len];
strncpy(dlg, "Missing Rainbow", len);
return dlg;
}
int main() {
size_t len = 30; char *p = createString(len);
string *sp = new (p) string(p, len);
cout << *sp << endl; return 0;
}
$ g++ place.cc
$ ./a.exe
Missing Rainbow
$ g++ --version
g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
$
All constructive comments welcome!
Rgds,
anna
--
Civil Disobedience
http://missingrainbow.blogspot.com/2008/07/civil-disobedience.html
> you prohably should avoid free(0)
Why? It is well defined to do nothing.
According to the C89 standard, section 4.10.3.2 (and C99, section
7.20.3.2):
"The free function causes the space pointed to by ptr to be deallocated,
that is, made available for further allocation. If ptr is a null
pointer, no action occurs."
> struct deleter
> {
> void operator () (void *p)
> { if(p) free(p);
> ]
> for the deleter is safer and since it is private can not be
> modified by user like a void (&)(void *) can,
Could you elaborate on what kind of modification you are referring to
here?
--
Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> 773 961-1620
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
> On 31 okt, 07:30, "Nevin :-] Liber" <ne...@eviloverlord.com> wrote:
> > In article
> > <bb17c808-51f3-4eee-8ea0-d743448d7...@64g2000hsu.googlegroups.com>,
> > francis_r <francis.ramme...@gmail.com> wrote:
> >
> > > How can I construct a string using a char pointer without making a
> > > copy, but simply by taking ownership of it?
> >
> > You can't. How would std::string even know how to release the space you
> > give it?
>
> Doesn't std::string just need to call 'free'?
Not necessarily. It uses std::allocator<char>, which calls ::operator
delete(void*), which may or not call free(), depending on the
implementation, whether or not the default implementation is replaced,
etc.
--
Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> 773 961-1620
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
I don't understand what you're doing here. How can you initialize an
std::string object with the same buffer on which the object is to be
placed, and expect it to work correctly? I can easily imagine the code
above will break on an implementation of std::string that uses <size_t,
char*> pair, because the input and output ranges of copying will overlap
but not coincide exactly.
Moreover, it's up to the implementation how std::string manages its
internal buffer, so it is dangerous and wrong to expect string::~string
to free the buffer with delete[] that pairs with the new[] that
createString used.
Back to the OP's question, I don't think the standard provides a
portable way to do what you want. Maybe the standard would have been
better if it had provided the memory management and the other various
string operations in two separate but combinable components. That way,
we could have had various flavours of string classes, including at least
complete-ownership-management, ownership-taking, and ownership-leaving.
--
Seungbeom Kim
typedef void (*Ptf)(void *);
As you wrote the code free is Ptf and any Ptf could be substituted
later since its type is public. [Its a plain old function ptr]
but if you add
private:
struct deleter {void operator () (void *p) {free(p);}
and use a default constructed deleter in the ctor of the shared_ptr
the
type is not publicly available so the deleter can't be changed by s
user.
Does this make sense???
--
> As you wrote the code free is Ptf and any Ptf could be substituted
> later since its type is public. [Its a plain old function ptr]
How does it get substituted? The member variable in question is private:
struct shared_c_string
{
shared_c_string(char* s = 0) : ptr(s, free) {}
operator const char*() const { return ptr.get(); }
private:
boost::shared_ptr<char> ptr;
};
> private:
> struct deleter {void operator () (void *p) {free(p);}
>
> and use a default constructed deleter in the ctor of the shared_ptr
> the
> type is not publicly available so the deleter can't be changed by s
> user.
>
> Does this make sense???
I'm still not getting it. If the variable isn't publicly accessible,
why does it matter what the underlying type of its internal deleter is?
If you could post some example code which demonstrates the problem
(changes the deleter for the private ptr member variable, unless I'm
misunderstanding what the actual problem is) it would aid greatly in
understanding the issue.
--
Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> 773 961-1620
[ See http://www.gotw.ca/resources/clcm.htm for info about ]