how is string::c_str() implemented?

G

Gianni Mariani

Jess said:
Hello,

I'm doing an exercise that defines a new abstract class "Str" that has
the same functions as "string" class, which holds a vector of chars.
But since I'm also trying to define a "c_str()" function, which copies
the chars from the vector into an array and return the pointer, I
think I need add another char array to my "Str" class. Now, the
problem is the size of the array has to be known in advance, but
obviously, the array's size changes when the corresponding
vector<char> changes. Any suggestions on how I should implement the
c_str() function?

c_str() simply needs to ensure that the character at one beyond the end
of the string contains a null. (i.e. '\000').

One way is to always allocate one more char than is needed and when
c_str() is called, plonk a nul at the end and return a pointer to your
internal buffer. This is probably the simplest solution.

Other solutions involve creating an auxiliary buffer as you noted.
 
J

Jess

Hello,

I'm doing an exercise that defines a new abstract class "Str" that has
the same functions as "string" class, which holds a vector of chars.
But since I'm also trying to define a "c_str()" function, which copies
the chars from the vector into an array and return the pointer, I
think I need add another char array to my "Str" class. Now, the
problem is the size of the array has to be known in advance, but
obviously, the array's size changes when the corresponding
vector<char> changes. Any suggestions on how I should implement the
c_str() function?

Thanks,
Jess
 
R

Rolf Magnus

Jess said:
Hello,

I'm doing an exercise that defines a new abstract class "Str" that has
the same functions as "string" class, which holds a vector of chars.
But since I'm also trying to define a "c_str()" function, which copies
the chars from the vector into an array and return the pointer, I
think I need add another char array to my "Str" class.

If you already have it as a vector of char, there is no need to copy it.
Now, the problem is the size of the array has to be known in advance, but
obviously, the array's size changes when the corresponding
vector<char> changes. Any suggestions on how I should implement the
c_str() function?

You could use a dynamically allocated array.
 
J

Jess

c_str() simply needs to ensure that the character at one beyond the end
of the string contains a null. (i.e. '\000').

One way is to always allocate one more char than is needed and when
c_str() is called, plonk a nul at the end and return a pointer to your
internal buffer. This is probably the simplest solution.

My internal buffer isn't an array, so perhaps I can't return a pointer
to it?
Other solutions involve creating an auxiliary buffer as you noted.

To create an auxiliary buffer, then I think I need to have a member
that is a char*, because I can't create a static array (since I don't
know its size in advance)...

Thanks,
Jess
 
J

Jess

If you already have it as a vector of char, there is no need to copy it.

Since c_str() returns an array of chars, do you mean I need to convert
the vector into an array?
You could use a dynamically allocated array.

Is there a way to keep a dynamically allocated array as a member of a
class? I guess it's impossible. Then I think I can keep a char* as a
member and let it point to a dynamically allocated array (after I do
"new char[...]"). Is this the correct approach?

Thanks,
Jess
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

Since c_str() returns an array of chars, do you mean I need to convert
the vector into an array?

Yes, a special property of std::vector is that all the elements are
guaranteed to be stored in contiguous memory (this means that all(?)
implementations of vector uses an array to store the elements. This
means that if you have a vector vec, then &vec[0] will give you a
pointer to the first element of the array used to store the elements.

So all you have to do is to make sure that you always keep an 0-char
at the end of the vector used to store your string in and then c_str()
will be as simple as 'return &vec[0];'. However remember that you have
the 0-char when you perform certain operations such as append so that
you don't add the new text after it.
You could use a dynamically allocated array.

Is there a way to keep a dynamically allocated array as a member of a
class? I guess it's impossible. Then I think I can keep a char* as a
member and let it point to a dynamically allocated array (after I do
"new char[...]"). Is this the correct approach?

Yes, you can have a char* as a member and each time the string changes
you delete[] the old one and new[] a new char array. However as
described above this is not necessary, nor is it a good solution since
it would mean that you kept two instances of the string, on in the
vector and one in the char*.
 
S

Sylvester Hesp

Erik Wikström said:
Since c_str() returns an array of chars, do you mean I need to convert
the vector into an array?

Yes, a special property of std::vector is that all the elements are
guaranteed to be stored in contiguous memory (this means that all(?)
implementations of vector uses an array to store the elements. This
means that if you have a vector vec, then &vec[0] will give you a
pointer to the first element of the array used to store the elements.

The horrendous vector<bool> of course being the sole exception to this rule.
;)

- Sylvester
 
J

Jess

Thanks!

Jess

Since c_str() returns an array of chars, do you mean I need to convert
the vector into an array?

Yes, a special property of std::vector is that all the elements are
guaranteed to be stored in contiguous memory (this means that all(?)
implementations of vector uses an array to store the elements. This
means that if you have a vector vec, then &vec[0] will give you a
pointer to the first element of the array used to store the elements.

So all you have to do is to make sure that you always keep an 0-char
at the end of the vector used to store your string in and then c_str()
will be as simple as 'return &vec[0];'. However remember that you have
the 0-char when you perform certain operations such as append so that
you don't add the new text after it.
Is there a way to keep a dynamically allocated array as a member of a
class? I guess it's impossible. Then I think I can keep a char* as a
member and let it point to a dynamically allocated array (after I do
"new char[...]"). Is this the correct approach?

Yes, you can have a char* as a member and each time the string changes
you delete[] the old one and new[] a new char array. However as
described above this is not necessary, nor is it a good solution since
it would mean that you kept two instances of the string, on in the
vector and one in the char*.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top