Sign in to follow this  

(C++) const char* to char* - how?

This topic is 3487 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Some functions or methods only return constant strings. But I want to be able to modify these strings as well. How could I do that? Thanks.

Share this post


Link to post
Share on other sites
Quote:
Some functions or methods only return constant strings. But I want to be able to modify these strings as well. How could I do that?
Create a mutable copy of the returned string, and work with the copy:
std::string text = function_that_returns_a_const_char_ptr();
// Do stuff with 'text'...

Share this post


Link to post
Share on other sites
Quote:
Original post by asdqwe
Some functions or methods only return constant strings. But I want to be able to modify these strings as well. How could I do that?
Thanks.

If a function returns a 'const char*', then that function is saying "here's a pointer to some memory with characters in it, but please don't modify this memory because it belongs to me". In other words, it's a bad idea to go modifying it.
For educational purposes though, the code to do this is:
const char* myConstCharPointer = ...;
char* badAndWrong = const_cast<char*>( myConstCharPointer );


Instead of doing the above, you should probably make a copy of the string and modify your own copy:
std::string newCopy = myConstCharPointer;

Or if you want to do it in C instead of C++:
char* newCopy = malloc( sizeof(char) * (strlen(myConstCharPointer)+1) );
strcpy( newCopy, myConstCharPointer );
//do stuff
free( newCopy );


Share this post


Link to post
Share on other sites
Quote:
Original post by Hodgman

const char* myConstCharPointer = ...;
char* badAndWrong = const_cast<char*>( myConstCharPointer );


Which is only legal if the pointee wasnt const to begin with.


const char* p = "Hello World!"; // unmodifiable string literal

char* q = new char[strlen(p) + 1];
strcpy(q, p);
const char* x = q;
char* y = const_cast<char*>(x); // legal, because *y isn't actually const

char* z = const_cast<char*>(p); // illegal, because *z is actually const

Share this post


Link to post
Share on other sites
Quote:
Original post by Hodgman
Or if you want to do it in C instead of C++:

If you wanted to do it in C, you'd just use strdup().

Share this post


Link to post
Share on other sites
Quote:
Original post by DevFred
*** Source Snippet Removed ***


Unfortunately, one of the stupidinteresting aspects of the C++ language inherited from C is that string literals can be assigned to non-const char pointers. Which means that a string literal is not necessarily unmodifiable. The language would be certainly cleaner if the were.

Share this post


Link to post
Share on other sites
Quote:
Original post by DevFred
Quote:
Original post by Hodgman

const char* myConstCharPointer = ...;
char* badAndWrong = const_cast<char*>( myConstCharPointer );


Which is only legal if the pointee wasnt const to begin with.


As I understand it, as long as you don't modify the string, it's also legal to cast a const char * to a char * using const_cast<>.

According to "The C++ Programming Language", that's the exact reason this cast was introduced at all, to allow for compatibility with legacy libraries and code that isn't const correct (or const aware at all).

The only action that should lead to undefined behavior is const_cast<>ing a const away and modifying the pointee, regardless of whether the original variable was declared as const or not.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Unfortunately, one of the stupidinteresting aspects of the C++ language inherited from C is that string literals can be assigned to non-const char pointers. Which means that a string literal is not necessarily unmodifiable. The language would be certainly cleaner if the were.
There is still hope, though. This conversion has been deprecated for 10 years (Annex D.4 of ISO C++98), and indeed gcc is complaining loudly about it now, if -Wall is enabled.
People considered the warning a "nuisance" in the past, which is why it was never enabled by default. It looks like the wind is turning, though :-)

With any luck, C++1x or C++2x comes out one day and cleans up with those deprecations for good. At least, such are my hopes.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Which means that a string literal is not necessarily unmodifiable.

The compiler will let you write that code, yes. But its behavior is undefined. Hm, are we saying the same thing?

Share this post


Link to post
Share on other sites
A philosophical question:

char * foo();

Let's say this function returns "Hello World\0".

Are you allowed to write "Hello World !\0" into that string?

Or more directly: how do you know how many chars you are allowed to write into such string, if you didn't allocate it?

In case of Hello World, is it safe to assume that you may write 11 characters + \0?

What if the string returned is a pointer into larger array:"ABC\0Hello World\0Hi there\0", so that return value is array[4]? And what if you replace the result with "Hello\0", thereby completely destroying the original structure into "ABC\0Hello\0World\0Hi there\0"?

Needless to say - char * strings have too many pitfalls, so this approach is essentially forbidden. This is why all such APIs do not return strings, but pass them into function by caller.

Share this post


Link to post
Share on other sites
Quote:
Original post by DevFred
Hm, are we saying the same thing?

Quote:
Original post by DevFred
const char* p = "Hello World!"; // unmodifiable string literal

Quote:
Original post by SiCrane
Which means that a string literal is not necessarily unmodifiable.

No. We aren't saying the same thing.

Share this post


Link to post
Share on other sites
SiCrane, I'm afraid I'm not clear what you are saying. Writing to a string literal is explicitly undefined behaviour (2.13.4.2). If you were merely pointing out that, depending on compiler, it might work, well... yes. The same way that double deleting a pointer might "work". Admittedly there is a distiction between the two, but not so much of one that I would go so far as to call string literals sometimes "modifiable".

Σnigma

Share this post


Link to post
Share on other sites

This topic is 3487 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this