Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   std::string on "const char *" (http://www.velocityreviews.com/forums/t956744-std-string-on-const-char.html)

Jarek Blakarz 01-21-2013 09:47 AM

std::string on "const char *"
 
Hi

Consider the following program:

const char *str = "my name";
std::string s(str);

std::string allocates the new memory on a heap.
I would like to force the std::string to initially work directly on a string
pointed to by "const char *str" and not allocate anything on a heap.
Of course later on when writing to a string occurs the COW is allowed.

Can I do that ? If so, HOW ?

thanks for answer

Nobody 01-21-2013 11:28 AM

Re: std::string on "const char *"
 
On Mon, 21 Jan 2013 01:47:46 -0800, Jarek Blakarz wrote:

> I would like to force the std::string to initially work directly on a string
> pointed to by "const char *str" and not allocate anything on a heap.
> Of course later on when writing to a string occurs the COW is allowed.
>
> Can I do that ? If so, HOW ?


No; std::string doesn't support that. It always allocates its own memory.

You can write your own string class, but that won't work with functions
which expect a std::string argument. And subclassing std::string won't
work as none of its methods are virtual, including its destructor.


Tiib 01-21-2013 01:47 PM

Re: std::string on "const char *"
 
On Monday, 21 January 2013 11:47:46 UTC+2, Jarek Blakarz wrote:
> Hi
>
> Consider the following program:
>
> const char *str = "my name";
> std::string s(str);


That is not C++ program, it does not compile on any C++ compilers I know of.
You probably meant:

#include <string>
int main()
{
const char *str = "my name";
std::string s(str);
}


> std::string allocates the new memory on a heap.


In lot (majority?) of implementations it does not. Lot of std::string
implementations use short string optimization and that means that the
"my name" is copied into stack (where that s resides). Other reason is
that C++ compiler may optimize the above code totally away since it
does nothing externally observable.

> I would like to force the std::string to initially work directly on a string
> pointed to by "const char *str" and not allocate anything on a heap.


Use the str then, why you need that s? A class that depends on external
management of resources that it "holds" is not worth making.

> Of course later on when writing to a string occurs the COW is allowed.
>
> Can I do that ? If so, HOW ?


Can you tell us why you need such a monster? I have not met much issues with
performance of std::string during past 15 years or so. My personal feeling
is that you are fixing something that is not broken by creating something
that IS broken.

Marcel Mller 01-21-2013 04:41 PM

Re: std::string on "const char *"
 
On 21.01.2013 10:47, Jarek Blakarz wrote:
> Hi
>
> Consider the following program:
>
> const char *str = "my name";
> std::string s(str);
>
> Can I do that ? If so, HOW ?


As the others suggested you need to write your own string class for this
purpose.

But if you want to go this way, I have some hints. (I have already done
this before.)

You will need *two* separate classes. One for ordinary strings and one
for compile time constant strings. The reason is quite easy: both accept
const char* as source for construction, but only one of them requires
that the lifetime of the storage behind the pointer exceeds the lifetime
of your string and maybe also copies of the string. C++11's constexpr
could be helpful.

Furthermore you need to decide whether you convert your constant string
to mutable strings at some place or if you modify you mutable string
class in a way that it does not free the storage of your constant
strings. The latter requires that length information and possibly a
reference count is not allocated in the same chunk of memory than the
string content. Fortunately this is common practice.

In fact you need a good reason to do all that, since it breaks
compatibility with std::string. Of course, you could provide a
conversion to std::string, but this would require a new allocation on
each conversion - a really bad idea.

In my case the reason was a C style plug-in interface that did not allow
dynamic allocations of storage that is shared between plug-in and main
program before an initialization function has been called.


Marcel

Seungbeom Kim 01-22-2013 02:46 AM

Re: std::string on "const char *"
 
On 2013-01-21 09:37, Paavo Helde wrote:
>
> Note that a program needs to convert static strings into std::strings
> only once. Static strings are part of the binary image on disk. Reading
> the data in from the disk is orders of magnitude slower than performing
> the in-memory copy for initializing std::string, so there is hardly any
> point in trying to optimize the latter. If loading static data is too
> slow you most probably need to get a faster hard drive instead.


But there's a difference in the memory footprint. With another layer
of dynamic allocation, the process consumes twice the address space
for each such string that could have remained only in the read-only
segment. In low-memory situations, this could cause other pages to be
swapped out to disk.

Of course, it is another story how likely is a program with such a
large amount of static data to affect the overall system performance.

--
Seungbeom Kim

Richard Damon 01-22-2013 04:46 AM

Re: std::string on "const char *"
 
On 1/21/13 9:46 PM, Seungbeom Kim wrote:
> On 2013-01-21 09:37, Paavo Helde wrote:
>>
>> Note that a program needs to convert static strings into std::strings
>> only once. Static strings are part of the binary image on disk. Reading
>> the data in from the disk is orders of magnitude slower than performing
>> the in-memory copy for initializing std::string, so there is hardly any
>> point in trying to optimize the latter. If loading static data is too
>> slow you most probably need to get a faster hard drive instead.

>
> But there's a difference in the memory footprint. With another layer
> of dynamic allocation, the process consumes twice the address space
> for each such string that could have remained only in the read-only
> segment. In low-memory situations, this could cause other pages to be
> swapped out to disk.
>
> Of course, it is another story how likely is a program with such a
> large amount of static data to affect the overall system performance.
>


The other side of the issue is that the constructor for this string
needs to know it its parameter really is a static string that will stay
around "forever", or is a temporary buffer that does need to be copied.

You can't really even count on using the const attribute, as it isn't
too hard to get that applied to a temporary buffer. Take the following
code as an example:


string makestring(const char* data) {
string s(data);
return s;
}



....
char buffer[30];
strcpy(buffer, "String 1");

string s1 = makestring(buffer);
strcpy(buffer, "String 2");


if the string constructor just uses the fact that it's parm has type
const char*, then at the end of the code, s1 holds the value
"String 2", since it would have thought that its input was a const
static string when it wasn't, and thus not make a copy of its input.


Also, if it did somehow have a way to really distinguish static strings
from other character buffer, than it would need to somehow store a flag
to determine if the old data pointer needs to be deleted, which may well
add a cost to every occurrence of the class.

88888 Dihedral 01-22-2013 06:45 AM

Re: std::string on "const char *"
 
在 2013年1月22日星期二UTC+8下午12时46分47 ,Richard Damon写道:
> On 1/21/13 9:46 PM, Seungbeom Kim wrote:
>
> > On 2013-01-21 09:37, Paavo Helde wrote:

>
> >>

>
> >> Note that a program needs to convert static strings into std::strings

>
> >> only once. Static strings are part of the binary image on disk. Reading

>
> >> the data in from the disk is orders of magnitude slower than performing

>
> >> the in-memory copy for initializing std::string, so there is hardly any

>
> >> point in trying to optimize the latter. If loading static data is too

>
> >> slow you most probably need to get a faster hard drive instead.

>
> >

>
> > But there's a difference in the memory footprint. With another layer

>
> > of dynamic allocation, the process consumes twice the address space

>
> > for each such string that could have remained only in the read-only

>
> > segment. In low-memory situations, this could cause other pages to be

>
> > swapped out to disk.

>
> >

>
> > Of course, it is another story how likely is a program with such a

>
> > large amount of static data to affect the overall system performance.

>
> >

>
>
>
> The other side of the issue is that the constructor for this string
>
> needs to know it its parameter really is a static string that will stay
>
> around "forever", or is a temporary buffer that does need to be copied.
>
>
>
> You can't really even count on using the const attribute, as it isn't
>
> too hard to get that applied to a temporary buffer. Take the following
>
> code as an example:
>
>
>
>
>
> string makestring(const char* data) {
>
> string s(data);
>
> return s;
>
> }
>
>
>
>
>
>
>
> ...
>
> char buffer[30];
>
> strcpy(buffer, "String 1");
>
>
>
> string s1 = makestring(buffer);
>
> strcpy(buffer, "String 2");
>
>
>
>
>
> if the string constructor just uses the fact that it's parm has type
>
> const char*, then at the end of the code, s1 holds the value
>
> "String 2", since it would have thought that its input was a const
>
> static string when it wasn't, and thus not make a copy of its input.
>
>
>
>
>
> Also, if it did somehow have a way to really distinguish static strings
>
> from other character buffer, than it would need to somehow store a flag
>
> to determine if the old data pointer needs to be deleted, which may well
>
> add a cost to every occurrence of the class.

There are subtle differences in wirting c++ programs
to be compiled in a library to be used by others,
and those with the main program with everything
compiled optimized extremely for those constants
not be exposed to others.




Jorgen Grahn 01-22-2013 10:36 AM

Re: std::string on "const char *"
 
On Tue, 2013-01-22, Richard Damon wrote:
....
> The other side of the issue is that the constructor for this string
> needs to know it its parameter really is a static string that will stay
> around "forever", or is a temporary buffer that does need to be copied.
>
> You can't really even count on using the const attribute, as it isn't
> too hard to get that applied to a temporary buffer.

[snip]

It's simply the usual old semantics: 'const Foo* foo;' doesn't in any
way guarantee that '*foo' cannot legally change. It just says you
cannot legally change it by using just 'foo'.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Richard Damon 01-22-2013 01:48 PM

Re: std::string on "const char *"
 
On 1/22/13 2:16 AM, Paavo Helde wrote:
>
> Note that once the data has been copied, the read-only pages can be
> swapped out from the working set again (i.e. discarded). This is done
> automatically by the OS in case of low memory AFAIK. So the memory
> consumption is not doubled in principle, it is only just the read-write
> pages are more expensive to deal with in case of memory exhaustion. IOW,
> if the memory is exhausted and all programs start trashing, a program
> using dynamic memory will trash worse than the one using static memory.
> Not sure if this scenario is worth optimizing.
>
> Cheers
> Paavo
>


It is worth pointing out that not all machines work this way. Most of
the programs I write will never meet a hard disk, and memory
availability is limited.

In this environment, I do strongly try to avoid making a std:string out
of static strings. If I have a string member that is always getting
initialized to a static string, it may be better to make that member a
char const*

If it is just most cases are static strings, than it may be worth
looking at ways to hold the result for the few dynamic cases to allow
the use of char const*

Jeff Flinn 01-22-2013 02:15 PM

Re: std::string on "const char *"
 
On 1/21/2013 4:47 AM, Jarek Blakarz wrote:
> Hi
>
> Consider the following program:
>
> const char *str = "my name";
> std::string s(str);
>
> std::string allocates the new memory on a heap.
> I would like to force the std::string to initially work directly on a string
> pointed to by "const char *str" and not allocate anything on a heap.
> Of course later on when writing to a string occurs the COW is allowed.
>
> Can I do that ? If so, HOW ?


Not sure it helps in you case but:

Google "string_ref". There is a standard proposal:
http://www.open-std.org/jtc1/sc22/wg...012/n3442.html, and a
recently added implementation in boost.

string_ref is separate from std::string though IIUC, has a common
interface and will be usable by templated code where a const
std::string& could be used.

Jeff



All times are GMT. The time now is 11:39 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.