Connecting Tech Pros Worldwide Help | Site Map

What's the difference between string::c_str() and string::data()?

Metro12
Guest
 
Posts: n/a
#1: Aug 23 '05
In the <basic_string.h>, I find the implementation of these two
functions. But I can't understand the difference between them.
Please give me some help!
//basic_string::c_str()
const _CharT*
c_str() const
{
// MT: This assumes concurrent writes are OK.
size_type __n = this->size();
traits_type::assign(_M_data()[__n], _Rep::_S_terminal);
return _M_data();
}

//basic_string::data()
const _CharT*
data() const { return _M_data(); }

Thanks!

peter.koch.larsen@gmail.com
Guest
 
Posts: n/a
#2: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?



Metro12 skrev:
[color=blue]
> In the <basic_string.h>, I find the implementation of these two
> functions. But I can't understand the difference between them.
> Please give me some help![/color]

A std::string is not null-terminated. While both functions return a
pointer to an array of the characters, std::string::c_str() make sure
that the array ends with \0.

/Peter

[snip][color=blue]
> Thanks![/color]

Bob Hairgrove
Guest
 
Posts: n/a
#3: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?


On 23 Aug 2005 00:46:33 -0700, "Metro12" <sanduoren@yahoo.com.cn>
wrote:
[color=blue]
>In the <basic_string.h>, I find the implementation of these two
>functions. But I can't understand the difference between them.
>Please give me some help!
> //basic_string::c_str()
> const _CharT*
> c_str() const
> {
> // MT: This assumes concurrent writes are OK.
> size_type __n = this->size();
> traits_type::assign(_M_data()[__n], _Rep::_S_terminal);
> return _M_data();
> }
>
> //basic_string::data()
> const _CharT*
> data() const { return _M_data(); }
>
>Thanks![/color]

One is guaranteed by the C++ standard to be null-terminated, the other
isn't (but might be).

--
Bob Hairgrove
NoSpamPlease@Home.com
Bob Hairgrove
Guest
 
Posts: n/a
#4: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?


On Tue, 23 Aug 2005 09:55:35 +0200, Bob Hairgrove
<invalid@bigfoot.com> wrote:
[color=blue][color=green]
>>In the <basic_string.h>, I find the implementation of these two
>>functions. But I can't understand the difference between them.[/color][/color]

[snip]
[color=blue]
>One is guaranteed by the C++ standard to be null-terminated, the other
>isn't (but might be).[/color]

Also, since std::string can contain binary data, including the null
character, the data() function would be more useful in those
situations. The pointer returned by c_str(), OTOH, is guaranteed to be
null-terminated and is typically used in legacy code which deals with
textual strings.

Although it would seem that c_str() could be used in either situation,
data() might NOT be null-terminated depending on the implementation.

--
Bob Hairgrove
NoSpamPlease@Home.com
Maxim Yegorushkin
Guest
 
Posts: n/a
#5: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?


peter.koch.larsen@gmail.com wrote:[color=blue]
> Metro12 skrev:
>[color=green]
> > In the <basic_string.h>, I find the implementation of these two
> > functions. But I can't understand the difference between them.
> > Please give me some help![/color]
>
> A std::string is not null-terminated. While both functions return a
> pointer to an array of the characters, std::string::c_str() make sure
> that the array ends with \0.[/color]

Not null terminating std::string is impractical. We have yet to see a
std::string without null terminator.

peter.koch.larsen@gmail.com
Guest
 
Posts: n/a
#6: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?



Maxim Yegorushkin skrev:
[color=blue]
> peter.koch.larsen@gmail.com wrote:[color=green]
> > Metro12 skrev:
> >[color=darkred]
> > > In the <basic_string.h>, I find the implementation of these two
> > > functions. But I can't understand the difference between them.
> > > Please give me some help![/color]
> >
> > A std::string is not null-terminated. While both functions return a
> > pointer to an array of the characters, std::string::c_str() make sure
> > that the array ends with \0.[/color]
>
> Not null terminating std::string is impractical. We have yet to see a
> std::string without null terminator.[/color]

This is an implementation-detail. I agree that the implementor of
std::string normally would reserve an extra char (and perhaps put \0 in
it) in order not to "get into troubles" if the user calls c_str.
But that 0 is not officially part of the string. Assume:

std::string s("Hello");
if (s[5] == '\0') ...

This last line is undefined behaviour although i would not be surprised
if the comparison was true.


/Peter

Bob Hairgrove
Guest
 
Posts: n/a
#7: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?


On 23 Aug 2005 03:39:28 -0700, peter.koch.larsen@gmail.com wrote:
[color=blue]
>std::string s("Hello");
>if (s[5] == '\0') ...
>
>This last line is undefined behaviour although i would not be surprised
>if the comparison was true.[/color]

On a conforming implementation, this throws std::out_of_range (see
21.3.4), therefore the behavior is defined.

--
Bob Hairgrove
NoSpamPlease@Home.com
krishanu.debnath@gmail.com
Guest
 
Posts: n/a
#8: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?



peter.koch.larsen@gmail.com wrote:[color=blue]
> Maxim Yegorushkin skrev:
>[/color]

<snip>
[color=blue][color=green]
> >
> > Not null terminating std::string is impractical. We have yet to see a
> > std::string without null terminator.[/color]
>
> This is an implementation-detail. I agree that the implementor of
> std::string normally would reserve an extra char (and perhaps put \0 in
> it) in order not to "get into troubles" if the user calls c_str.
> But that 0 is not officially part of the string. Assume:
>
> std::string s("Hello");
> if (s[5] == '\0') ...
>
> This last line is undefined behaviour although i would not be surprised
> if the comparison was true.[/color]

Why do you think last line invokes UB? Sec 21.3.4 clearly says that
behavior
is undefined only if index is greater than size().

Krishanu

peter.koch.larsen@gmail.com
Guest
 
Posts: n/a
#9: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?



Bob Hairgrove skrev:
[color=blue]
> On 23 Aug 2005 03:39:28 -0700, peter.koch.larsen@gmail.com wrote:
>[color=green]
> >std::string s("Hello");
> >if (s[5] == '\0') ...
> >
> >This last line is undefined behaviour although i would not be surprised
> >if the comparison was true.[/color]
>
> On a conforming implementation, this throws std::out_of_range (see
> 21.3.4), therefore the behavior is defined.[/color]

I do not use the constant of operator[]. I do not have the standard
myself, but according to Josuttis book this implies that my index
should be between 0 and s.size() - 1. So you claim is that Josuttis is
wrong? In that case I (and Josuttis ;-) will stand corrected.

/Peter
[color=blue]
>
> --
> Bob Hairgrove
> NoSpamPlease@Home.com[/color]

peter.koch.larsen@gmail.com
Guest
 
Posts: n/a
#10: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?



peter.koch.lar...@gmail.com skrev:[color=blue]
> I do not use the constant of operator[].[/color]
should read:
I do not use the constant version of operator[].


/Peter

krishanu.debnath@gmail.com
Guest
 
Posts: n/a
#11: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?



Bob Hairgrove wrote:[color=blue]
> On 23 Aug 2005 03:39:28 -0700, peter.koch.larsen@gmail.com wrote:
>[color=green]
> >std::string s("Hello");
> >if (s[5] == '\0') ...
> >
> >This last line is undefined behaviour although i would not be surprised
> >if the comparison was true.[/color]
>
> On a conforming implementation, this throws std::out_of_range (see
> 21.3.4), therefore the behavior is defined.
>[/color]

Which element access operator you are talking about? Here is what
standard says ..

21.3.4 - basic_string element access [lib.string.access]

const_reference operator[](size_type pos) const;
reference operator[](size_type pos);

-1- Returns: If pos < size(), returns data()[ pos ]. Otherwise, if pos
== size(), the const version returns charT(). Otherwise, the behavior
is undefined.

const_reference at(size_type pos) const;
reference at(size_type pos);

-2- Requires: pos < size()

-3- Throws: out_of_range if pos >= size().

-4- Returns: operator[]( pos ).

Krishanu

peter.koch.larsen@gmail.com
Guest
 
Posts: n/a
#12: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?



krishanu.debnath@gmail.com skrev:
[color=blue]
> peter.koch.larsen@gmail.com wrote:[color=green]
> > Maxim Yegorushkin skrev:
> >[/color]
>
> <snip>
>[color=green][color=darkred]
> > >
> > > Not null terminating std::string is impractical. We have yet to see a
> > > std::string without null terminator.[/color]
> >
> > This is an implementation-detail. I agree that the implementor of
> > std::string normally would reserve an extra char (and perhaps put \0 in
> > it) in order not to "get into troubles" if the user calls c_str.
> > But that 0 is not officially part of the string. Assume:
> >
> > std::string s("Hello");
> > if (s[5] == '\0') ...
> >
> > This last line is undefined behaviour although i would not be surprised
> > if the comparison was true.[/color]
>
> Why do you think last line invokes UB? Sec 21.3.4 clearly says that
> behavior
> is undefined only if index is greater than size().[/color]

Well - from my reading (a preliminary version on the net, but I doubt
that changes have been made in this area) it is clear to me that index
must be smaller than size() (or length() if you prefer) unless the
const version is called. Note that my code used the non-const
operator[].

/Peter[color=blue]
>
> Krishanu[/color]

Bob Hairgrove
Guest
 
Posts: n/a
#13: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?


On 23 Aug 2005 04:55:41 -0700, peter.koch.larsen@gmail.com wrote:
[color=blue]
>
>Bob Hairgrove skrev:
>[color=green]
>> On 23 Aug 2005 03:39:28 -0700, peter.koch.larsen@gmail.com wrote:
>>[color=darkred]
>> >std::string s("Hello");
>> >if (s[5] == '\0') ...
>> >
>> >This last line is undefined behaviour although i would not be surprised
>> >if the comparison was true.[/color]
>>
>> On a conforming implementation, this throws std::out_of_range (see
>> 21.3.4), therefore the behavior is defined.[/color]
>
>I do not use the constant of operator[]. I do not have the standard
>myself, but according to Josuttis book this implies that my index
>should be between 0 and s.size() - 1. So you claim is that Josuttis is
>wrong? In that case I (and Josuttis ;-) will stand corrected.[/color]

Oops, you are correct ... I was reading the details for the at()
function. Sorry for the confusion!

According to the operator[] description, it returns charT() if
pos==size().

--
Bob Hairgrove
NoSpamPlease@Home.com
Bob Hairgrove
Guest
 
Posts: n/a
#14: Aug 23 '05

re: What's the difference between string::c_str() and string::data()?


On 23 Aug 2005 05:30:44 -0700, krishanu.debnath@gmail.com wrote:
[color=blue]
>
>Bob Hairgrove wrote:[color=green]
>> On 23 Aug 2005 03:39:28 -0700, peter.koch.larsen@gmail.com wrote:
>>[color=darkred]
>> >std::string s("Hello");
>> >if (s[5] == '\0') ...
>> >
>> >This last line is undefined behaviour although i would not be surprised
>> >if the comparison was true.[/color]
>>
>> On a conforming implementation, this throws std::out_of_range (see
>> 21.3.4), therefore the behavior is defined.
>>[/color]
>
>Which element access operator you are talking about? Here is what
>standard says ..
>
>21.3.4 - basic_string element access [lib.string.access]
>
>const_reference operator[](size_type pos) const;
>reference operator[](size_type pos);
>
>-1- Returns: If pos < size(), returns data()[ pos ]. Otherwise, if pos
>== size(), the const version returns charT(). Otherwise, the behavior
>is undefined.
>
>const_reference at(size_type pos) const;
>reference at(size_type pos);
>
>-2- Requires: pos < size()
>
>-3- Throws: out_of_range if pos >= size().
>
>-4- Returns: operator[]( pos ).
>[/color]

Yes, I was looking at the description for the at() function. Sorry!

--
Bob Hairgrove
NoSpamPlease@Home.com
Larry I Smith
Guest
 
Posts: n/a
#15: Aug 24 '05

re: What's the difference between string::c_str() and string::data()?


Maxim Yegorushkin wrote:[color=blue]
> peter.koch.larsen@gmail.com wrote:[color=green]
>> Metro12 skrev:
>>[color=darkred]
>>> In the <basic_string.h>, I find the implementation of these two
>>> functions. But I can't understand the difference between them.
>>> Please give me some help![/color]
>> A std::string is not null-terminated. While both functions return a
>> pointer to an array of the characters, std::string::c_str() make sure
>> that the array ends with \0.[/color]
>
> Not null terminating std::string is impractical. We have yet to see a
> std::string without null terminator.
>[/color]

Most of our std::string usage is to hold binary data (image files,
etc). Automatically nul-terminating a std::string is of no
particular use. Use c_str() if a nul-terminated version is needed,
or data() if you merely need access to the raw bytes; in either case
length() gives the actual data length (whether or not the raw data
is binary data).

Regards,
Larry
Old Wolf
Guest
 
Posts: n/a
#16: Aug 24 '05

re: What's the difference between string::c_str() and string::data()?


Maxim Yegorushkin wrote:[color=blue]
> peter.koch.larsen@gmail.com wrote:[color=green]
> > Metro12 skrev:
> >[color=darkred]
> > > In the <basic_string.h>, I find the implementation of these two
> > > functions. But I can't understand the difference between them.
> > > Please give me some help![/color]
> >
> > A std::string is not null-terminated. While both functions return a
> > pointer to an array of the characters, std::string::c_str() make sure
> > that the array ends with \0.[/color]
>
> Not null terminating std::string is impractical. We have yet to see a
> std::string without null terminator.[/color]

I have read that standard library implementations maintain
a counted string, and only append a \0 when someone calls c_str().

I don't see how it is more practical for an implementation to
have to manipulate zeroes all the time, it would seem to me
that it's easier just to deal with the counted number of bytes.

krishanu.debnath@gmail.com
Guest
 
Posts: n/a
#17: Aug 24 '05

re: What's the difference between string::c_str() and string::data()?



peter.koch.larsen@gmail.com wrote:[color=blue]
> krishanu.debnath@gmail.com skrev:
>[/color]

<snip>
[color=blue][color=green][color=darkred]
> > >
> > > std::string s("Hello");
> > > if (s[5] == '\0') ...
> > >
> > > This last line is undefined behaviour although i would not be surprised
> > > if the comparison was true.[/color]
> >
> > Why do you think last line invokes UB? Sec 21.3.4 clearly says that
> > behavior
> > is undefined only if index is greater than size().[/color]
>
> Well - from my reading (a preliminary version on the net, but I doubt
> that changes have been made in this area) it is clear to me that index
> must be smaller than size() (or length() if you prefer) unless the[/color]

We can only justify the behavior by whats written in standard, not by
any
material you see on net.

Krishanu

peter.koch.larsen@gmail.com
Guest
 
Posts: n/a
#18: Aug 24 '05

re: What's the difference between string::c_str() and string::data()?



krishanu.debnath@gmail.com skrev:
[color=blue]
> peter.koch.larsen@gmail.com wrote:[color=green]
> > krishanu.debnath@gmail.com skrev:
> >[/color]
>
> <snip>
>[color=green][color=darkred]
> > > >
> > > > std::string s("Hello");
> > > > if (s[5] == '\0') ...
> > > >
> > > > This last line is undefined behaviour although i would not be surprised
> > > > if the comparison was true.
> > >
> > > Why do you think last line invokes UB? Sec 21.3.4 clearly says that
> > > behavior
> > > is undefined only if index is greater than size().[/color]
> >
> > Well - from my reading (a preliminary version on the net, but I doubt
> > that changes have been made in this area) it is clear to me that index
> > must be smaller than size() (or length() if you prefer) unless the[/color]
>
> We can only justify the behavior by whats written in standard, not by
> any
> material you see on net.[/color]

Well... most of the draft standard on the net is pretty accurate. But
let me quote the standard quote from one of your other posts in this
thread:

<begin quote>
21.3.4 - basic_string element access [lib.string.access]


const_reference operator[](size_type pos) const;
reference operator[](size_type pos);


-1- Returns: If pos < size(), returns data()[ pos ]. Otherwise, if pos
== size(), the const version returns charT(). Otherwise, the behavior
is undefined.

<end quote>

This part is word by word the same as the draft I read. Clearly both
quotes support my view:
[color=blue][color=green][color=darkred]
> > > >
> > > > std::string s("Hello");
> > > > if (s[5] == '\0') ...
> > > >
> > > > This last line is undefined behaviour although i would not be surprised
> > > > if the comparison was true.
> > >[/color][/color][/color]
[color=blue]
>
> Krishanu[/color]

/Peter

krishanu.debnath@gmail.com
Guest
 
Posts: n/a
#19: Aug 24 '05

re: What's the difference between string::c_str() and string::data()?



peter.koch.lar...@gmail.com wrote:[color=blue]
> krishanu.debnath@gmail.com skrev:
>[color=green]
> > peter.koch.larsen@gmail.com wrote:[color=darkred]
> > > krishanu.debnath@gmail.com skrev:
> > >[/color]
> >
> > <snip>
> >[color=darkred]
> > > > >
> > > > > std::string s("Hello");
> > > > > if (s[5] == '\0') ...
> > > > >
> > > > > This last line is undefined behaviour although i would not be surprised
> > > > > if the comparison was true.
> > > >
> > > > Why do you think last line invokes UB? Sec 21.3.4 clearly says that
> > > > behavior
> > > > is undefined only if index is greater than size().
> > >
> > > Well - from my reading (a preliminary version on the net, but I doubt
> > > that changes have been made in this area) it is clear to me that index
> > > must be smaller than size() (or length() if you prefer) unless the[/color]
> >
> > We can only justify the behavior by whats written in standard, not by
> > any
> > material you see on net.[/color]
>
> Well... most of the draft standard on the net is pretty accurate. But
> let me quote the standard quote from one of your other posts in this
> thread:
>
> <begin quote>
> 21.3.4 - basic_string element access [lib.string.access]
>
>
> const_reference operator[](size_type pos) const;
> reference operator[](size_type pos);
>
>
> -1- Returns: If pos < size(), returns data()[ pos ]. Otherwise, if pos
> == size(), the const version returns charT(). Otherwise, the behavior
> is undefined.
>
> <end quote>
>
> This part is word by word the same as the draft I read. Clearly both
> quotes support my view:[/color]

My goof. I overlook the words 'const version'.

Krishanu

Closed Thread


Similar C / C++ bytes