[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

non-const version of std::string::data

dp1978x

11/24/2008 8:21:00 PM

Hi,

is the following legal?

std::string x;
// ...
assert (!x.empty());
x.data()[0] = 'b';

I think not, AFAIK there's no non-const version of "data()", could
someone confirm?

How about this then:

std::string x;
// ...
assert (!x.empty());
const_cast <char *>(x.data())[0] = 'b';

Background: I have a C library that fills array of characters passed
to it by the caller. I need to convert the returned strings to
std::string. I would prefer to do this directly w/o allocating any
temporaries.

Thanks,
D.
17 Answers

Paavo Helde

11/24/2008 8:58:00 PM

0

dp1978x@gmail.com kirjutas:

> Hi,
>
> is the following legal?
>
> std::string x;
> // ...
> assert (!x.empty());
> x.data()[0] = 'b';
>
> I think not, AFAIK there's no non-const version of "data()", could
> someone confirm?

There is: &x[0]

hth
Paavo

dp1978x

11/24/2008 9:10:00 PM

0

On Nov 24, 3:57 pm, Paavo Helde <pa...@nospam.please.org> wrote:
> dp19...@gmail.com kirjutas:
>
> > Hi,
>
> > is the following legal?
>
> > std::string x;
> > // ...
> > assert (!x.empty());
> > x.data()[0] = 'b';
>
> > I think not, AFAIK there's no non-const version of "data()", could
> > someone confirm?
>
> There is: &x[0]
>
> hth
> Paavo

Okay, bad example. I need a non-const pointer to the underlying array
of characters, so that all characters in the range [0..length) are
addressible.

So will "(&x[0])[n]" where 0 <= n < length work?

D.

Paavo Helde

11/24/2008 9:13:00 PM

0

Paavo Helde <paavo@nospam.please.org> kirjutas:

> dp1978x@gmail.com kirjutas:
>
>> Hi,
>>
>> is the following legal?
>>
>> std::string x;
>> // ...
>> assert (!x.empty());
>> x.data()[0] = 'b';
>>
>> I think not, AFAIK there's no non-const version of "data()", could
>> someone confirm?
>
> There is: &x[0]

More verbosely, I should probably note that the contiguity of the string
buffer obtained by &x[0] is not guaranteed by the standard, but all known
C++ implementations are following that, and the requirement will be present
in the next standard AFAIK.

Paavo

Paavo Helde

11/24/2008 9:16:00 PM

0

dp1978x@gmail.com kirjutas:

> On Nov 24, 3:57 pm, Paavo Helde <pa...@nospam.please.org> wrote:
>> dp19...@gmail.com kirjutas:
>>
>> > Hi,
>>
>> > is the following legal?
>>
>> > std::string x;
>> > // ...
>> > assert (!x.empty());
>> > x.data()[0] = 'b';
>>
>> > I think not, AFAIK there's no non-const version of "data()", could
>> > someone confirm?
>>
>> There is: &x[0]
>>
>> hth
>> Paavo
>
> Okay, bad example. I need a non-const pointer to the underlying array
> of characters, so that all characters in the range [0..length) are
> addressible.
>
> So will "(&x[0])[n]" where 0 <= n < length work?

Yes, I understood your question, it should work in practice (see my other
post). If you want strict guarantee also by the current standard, use
std::vector<char>.

Paavo

Juha Nieminen

11/24/2008 9:40:00 PM

0

Paavo Helde wrote:
> More verbosely, I should probably note that the contiguity of the string
> buffer obtained by &x[0] is not guaranteed by the standard, but all known
> C++ implementations are following that, and the requirement will be present
> in the next standard AFAIK.

Do practical implementations of std::string always use a contiguous
array (in the same as std::vector) because it makes it much more
efficient for the std::string::c_str() to do its job (basically it just
needs to append a '\0' and then return a pointer to the array)?

dp1978x

11/24/2008 9:45:00 PM

0

On Nov 24, 4:15 pm, Paavo Helde <pa...@nospam.please.org> wrote:
> dp19...@gmail.com kirjutas:
>
> Yes, I understood your question, it should work in practice (see my other
> post). If you want strict guarantee also by the current standard, use
> std::vector<char>.
>
> Paavo

Thanks! So just to be clear: in the current standard operator[] in
vector<> _does_ guaruantee this, but not basic_string?

D.

dp1978x

11/24/2008 9:49:00 PM

0

On Nov 24, 4:40 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> Do practical implementations of std::string always use a contiguous
> array (in the same as std::vector) because it makes it much more
> efficient for the std::string::c_str() to do its job (basically it just
> needs to append a '\0' and then return a pointer to the array)?

I would think most implementations always keep the buffer up-to-date
w.r.t. c_str() by NUL-terminating it in every modifier function, so
c_str() simply returns a pointer. Not that it matters much.

Paavo Helde

11/24/2008 9:53:00 PM

0

dp1978x@gmail.com kirjutas:

> On Nov 24, 4:15 pm, Paavo Helde <pa...@nospam.please.org> wrote:
>> dp19...@gmail.com kirjutas:
>>
>> Yes, I understood your question, it should work in practice (see my
>> other post). If you want strict guarantee also by the current
>> standard, use std::vector<char>.
>>
>> Paavo
>
> Thanks! So just to be clear: in the current standard operator[] in
> vector<> _does_ guaruantee this, but not basic_string?

Yes, to my understanding.

Paavo

Paavo Helde

11/24/2008 10:11:00 PM

0

Juha Nieminen <nospam@thanks.invalid> kirjutas:

> Paavo Helde wrote:
>> More verbosely, I should probably note that the contiguity of the
>> string buffer obtained by &x[0] is not guaranteed by the standard,
>> but all known C++ implementations are following that, and the
>> requirement will be present in the next standard AFAIK.
>
> Do practical implementations of std::string always use a contiguous
> array (in the same as std::vector) because it makes it much more
> efficient for the std::string::c_str() to do its job (basically it
> just needs to append a '\0' and then return a pointer to the array)?

It also has to do with thread-safety. Although the current standard does
not mention multithreading, a quality implementation attempts to provide
some useful support for it. For the string objects, them being value
types, this means that they should not mutate physically in const member
functions. This means that the c_str() and data() member functions cannot
alter the actual string buffer, for example making a contiguous array
from the non-contiguous pieces the string was held in so far. At most
they could construct a new buffer and return pointer to it, but in this
case the question of memory ownership comes up; this could be resolved by
having some pool of owned buffers inside the string object, but I guess
this already becomes an overkill for such a basic class. It seems the
simplest and most robust version is to have a single contiguous buffer,
always zero-terminated for the case somebody might call c_str(), and
modified only by mutating member functions.

Note, these are just my thoughts about the subject, I have not
implemented standard library, so I may be deeply mistaken.

Paavo



James Kanze

11/24/2008 10:48:00 PM

0

On Nov 24, 9:21 pm, dp19...@gmail.com wrote:
> is the following legal?

>   std::string x;
>   // ...
>   assert (!x.empty());
>   x.data()[0] = 'b';

> I think not, AFAIK there's no non-const version of "data()",
> could someone confirm?

There isn't yet. I'd heard that there was supposed to be one
soon, but I don't see it in my copy of the CD, so maybe I'm
mistaken. In the meantime, &x[0] will work if the string isn't
empty.

> How about this then:

>   std::string x;
>   // ...
>   assert (!x.empty());
>   const_cast <char *>(x.data())[0] = 'b';

> Background: I have a C library that fills array of characters
> passed to it by the caller. I need to convert the returned
> strings to std::string. I would prefer to do this directly w/o
> allocating any temporaries.

I think you're better off using &x[0]. It seems to be the
accepted idiom for std::vector (which will have a non-const
data() function).

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34