again on const_cast and .c_str() 
Author Message
 again on const_cast and .c_str()

I want to encrypt a std::string object and I've got a c API function which
is granted not to write outside of the char* it received.
i.e. something like:
void BasicEncrypt(char* ptr, size_t length);
// on exit, ptr holds the encrypted string, which is still 'length' chars
long

Is it safe to do something like this:

void STLEncrypt( std:string& s )
{
    BasicEncrypt( const_cast<char*>( s.c_str() ), s.size() );

Quote:
}

Since I take the string by non-const&, whatever pointer c_str returns,
should be in writable memory (unless the STL implementation implements a
c_str method which allocates a new memory block -- but is there any?)

Is there any way STLEncrypt can fail?
Thanks in advance

--
 A solution is a solution.
-- Mycroft Holmes



Tue, 13 Dec 2005 14:49:45 GMT  
 again on const_cast and .c_str()

Quote:
> void BasicEncrypt(char* ptr, size_t length);

> void STLEncrypt( std:string& s )
> {
>     BasicEncrypt( const_cast<char*>( s.c_str() ), s.size() );
> }

I would never do this. The pointer returned by s.c_str() is really
implementation dependent.

Copy the contents of the string-object into a char-buffer, encrypt it
and assign the result back to the string-object.

Be sure, the encryption does not lead to 0-Bytes in the string.

T.M.



Tue, 13 Dec 2005 15:00:11 GMT  
 again on const_cast and .c_str()

Quote:
> I would never do this. The pointer returned by s.c_str() is really
> implementation dependent.

thanks.
in fact I already reverted to using a temporary std::vector<char>.
but is there any known implementation where the 'const_cast' approach will
fail?

--
 A solution is a solution.
-- Mycroft Holmes



Tue, 13 Dec 2005 15:29:38 GMT  
 again on const_cast and .c_str()

Quote:
> > I would never do this. The pointer returned by s.c_str() is really
> > implementation dependent.

> in fact I already reverted to using a temporary std::vector<char>.

Really?! Why not a char buf[1024]???

Quote:
> but is there any known implementation where the 'const_cast'
> approach will fail?

I don't test it. But I would not be sure what's happening if the
buffer is manipulated. What is when 0-Bytes get in? What is with
sharing the inner buffer between several string-objects? I mean, const
should remain const. There's a reason for being const. At least it is
bad programming style - other people will not assume that you modify a
const object.

T.M.



Tue, 13 Dec 2005 15:40:55 GMT  
 again on const_cast and .c_str()

Quote:
> > in fact I already reverted to using a temporary std::vector<char>.

> Really?! Why not a char buf[1024]???

because I don't know how long the string could be ;)

Quote:
> At least it is
> bad programming style - other people will not assume that you modify a
> const object.

I definetly agree.


Tue, 13 Dec 2005 16:18:39 GMT  
 again on const_cast and .c_str()

Quote:

>>I would never do this. The pointer returned by s.c_str() is really
>>implementation dependent.

> thanks.
> in fact I already reverted to using a temporary std::vector<char>.
> but is there any known implementation where the 'const_cast' approach will
> fail?

I would imagine that you could get VC6 to fail with this approach
VC6 uses COW for the string so by casting and changing you could be
inadvertently changing other strings in the back-ground

        Vin



Tue, 13 Dec 2005 17:06:42 GMT  
 again on const_cast and .c_str()

Quote:
> Is there any way STLEncrypt can fail?

Easily. There is no guarantee that c_str() returns a pointer to the same
characters that the string holds. The string could make a copy, append '\0'
and return that. You would then be attempting to modify the copy, not the
original string.

With basic_string there is no guarantee that the characters are held
contigously.

If you want to interact with C API's you should use vector<char> and pass

&v[0]

Stephen Howe

Quote:
> Thanks in advance

> --
>  A solution is a solution.
> -- Mycroft Holmes



Tue, 13 Dec 2005 20:28:43 GMT  
 again on const_cast and .c_str()
On Fri, 27 Jun 2003 09:29:38 +0200, "Mycroft Holmes"

Quote:

>> I would never do this. The pointer returned by s.c_str() is really
>> implementation dependent.

>thanks.
>in fact I already reverted to using a temporary std::vector<char>.
>but is there any known implementation where the 'const_cast' approach will
>fail?

Yes, under VC6, you will end up modifying any strings shared with the
passed one!

If you change the implementation to

void STLEncrypt( std:string& s )
{
        s[0]; //unshared with other strings
    BasicEncrypt( const_cast<char*>( s.c_str() ), s.size() );

Quote:
}

then I don't know of any implementations where it will fail, but you
never know.

std::string is not designed for long strings really. If you want a
large character buffer, vector<char> is better.

Tom



Tue, 13 Dec 2005 21:59:46 GMT  
 again on const_cast and .c_str()



Quote:

> std::string is not designed for long strings really. If you want a
> large character buffer, vector<char> is better.

I am not sure that is generally good advise.

string and vector is very similar, if you have a string that is not
reference counted. string is optimized for small value types that can
be memcpy'd, while vector must also handle large objects that require
constructors and destructors.

Bo Persson



Wed, 14 Dec 2005 02:41:21 GMT  
 again on const_cast and .c_str()


Quote:



>> std::string is not designed for long strings really. If you want a
>> large character buffer, vector<char> is better.

>I am not sure that is generally good advise.

>string and vector is very similar, if you have a string that is not
>reference counted. string is optimized for small value types that can
>be memcpy'd, while vector must also handle large objects that require
>constructors and destructors.

Decent vector implementations are also optimized for built in types.
push_back is guaranteed to be amortized constant time, and the vector
can't go shrinking its capacity behind your back (as some string
implementations have been known to do!).

Because of the implementation leeway allowed in std::string, I
consider it fairly useless for operating on large amounts of data
(where performance becomes an issue), since different operations are
fast and slow on different implementations, so you can end up with
wildly differing runtimes for a program depending on the library
implementation (we're talking factors of 100x and greater).

Tom



Wed, 14 Dec 2005 03:15:38 GMT  
 again on const_cast and .c_str()
On Fri, 27 Jun 2003 08:49:45 +0200, "Mycroft Holmes"

Quote:

>Is it safe to do something like this:

>void STLEncrypt( std:string& s )
>{
>    BasicEncrypt( const_cast<char*>( s.c_str() ), s.size() );
>}

>Since I take the string by non-const&, whatever pointer c_str returns,
>should be in writable memory (unless the STL implementation implements a
>c_str method which allocates a new memory block -- but is there any?)

Just curious: Would using std::string.data() be a bad move as well?

"Pain and disappointment are inevitable. Misery is optional."

-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----



Thu, 22 Dec 2005 07:51:22 GMT  
 again on const_cast and .c_str()



Quote:
> On Fri, 27 Jun 2003 08:49:45 +0200, "Mycroft Holmes"

> >Is it safe to do something like this:

> >void STLEncrypt( std:string& s )
> >{
> >    BasicEncrypt( const_cast<char*>( s.c_str() ), s.size() );
> >}

> >Since I take the string by non-const&, whatever pointer c_str
returns,
> >should be in writable memory (unless the STL implementation
implements a
> >c_str method which allocates a new memory block -- but is there

any?)

There are (or has been) some reference counted implementations where
the character buffer could be shared between different strings. If you
modify the buffer, you might update all of these strings.

Quote:

> Just curious: Would using std::string.data() be a bad move as well?

Yes, it would. Implementations are allowed to return a copy of the
string's value, as strings are not required to store the whole string
in one buffer. Unlike vector.

The standard says: "The program shall not alter any of the values
stored in the character array."

Pretty explicit!

Bo Persson



Thu, 22 Dec 2005 19:06:29 GMT  
 
 [ 12 post ] 

 Relevant Pages 

1. Error with const_cast<...>, porting from a VC6 project

2. STL string and const_cast

3. const_cast behavior

4. how to avoid const_cast

5. string.c_str( )???

6. std::string class c_str() const workaround?

7. basic_string<>::data() vs basic_string<>::c_str()

8. (LPTSTR)(strEmailAddress.c_str()) crashes my program

9. string.c_str( ) ???

10. std::string and c_str()

11. What can I do to c_str()?

12. multithreading, again and again!

 

 
Powered by phpBB® Forum Software