Is it ok to mix cstrings and strings?

Hi, I wroted a function to check if a string is a palindrome, I first used cstrings so I can create a double pointer which I can move along each character and make things easier at the start. But then I needed to create a new string with the entire sentence without whitespace, too allow me to check if it is a palindrome more easily, so for that I created a temporary std::string which I += each character. Is it bad practice to mix cstrings and std::strings in c++? As afaik, new strings are supposed to be a replacement for normal cstrings because it handles alot of the memory management etc. I also needed the length of a string, which I can do easily enough with a simple function with a cstring, but normal strings have a length function built in, so which should I use?


Also, If I say the following:

 
char* message = " I am a message";//...does that allocate that memory on the //heap as if I do char* message = new char[16];? 


Thanks
Is it ok to mix cstrings and strings?

This is a question of elegance (or lack thereof) and not strictly a question of correctness.
You should stick to using C++ std::string as they are easier to use.

1
2
3
char* message = " I am a message";
//...does that allocate that memory on the
//heap as if I do char* message = new char[16];? 


No.
" I am a message" is a string literal stored most likely in the read-only segment of the program, and message is a pointer that keeps its memory address.

This is why modifying the array through message shouldn't work, and is why message should be a const pointer to begin with.

1
2
3
4
// char* message = " I am a message";
// message[0] = '>';

const char *message = " I am a message";

You should use std::string unless you have a very good reason not to.

Changing between char arrays and std::strings can be done, but is wasteful, since each time you "change" you're copying the entire string over. It also can be error prone.


Also:
1
2
char* message = " I am a message";//...does that allocate that memory on the
//heap as if I do char* message = new char[16];? 


No. In fact... you should NEVER do this with a non-const pointers. These types of literals must ALWAYS be const. Compilers only allow non-const here to support legacy code, but it is terrible terrible.

1
2
const char* message = " I am a message"; // perfectly acceptable
char* foo = " die die die";  // BAD BAD NEVER DO IT 



What happens is the string data gets put in a special segment of memory when the program is loaded. This memory is almost always read-only and therefore any attempt to write to it will almost certainly cause an access violation and cause your program to crash.

So no... creating a pointer in this case does not allocate memory as if you did new... but rather it merely points to the static memory where the string data has been loaded.


EDIT: ninja'd by catfish
Last edited on
Ok thanks for the reply, 1 question which may seem obvious:

Can I have as much control with std::string as with normal cstrings? Is there any downside to std::string?
Can I have as much control with std::string as with normal cstrings?

What do you mean, when you say "control"?
Can I have as much control with std::string as with normal cstrings?


Not always. You can do some pointer math tricks with char arrays that can't easily be accomplished with std::string. However such tricks are usually ill advised in the first place.

There are times when char arrays are preferable. But really, they're not as common as you might think.
I mean like, at the moment I have a function like this:

1
2
3
4
5
6
//allows to skip whitespace characters and return the next non-whitespace character in a sequence
char strip_ws(const char** pc)
{
	 while (**pc == ' ') ++(*pc);
	  return **pc;
}


Is it possible to do this sort of things on std::strings? Or even is there a function built into std::string which allow you to specify "some character" to skip?
That is the weird, usually ill-advised pointer math I was talking about before.

You can't easily do that with std::string... but you probably shouldn't be doing that to begin with.

Assuming the goal here is to remove all spaces from a string:
1
2
3
4
5
6
7
8
#include <string>
#include <algorithm>

std::string x = "a string with whitespace.";

x.erase( std::remove( x.begin(), x.end(), ' '), x.end() ); // remove all whitespace

cout << x;  // prints "astringwithwhitespace." 
Last edited on
Thanks,

Can you possibly explain why they are ill advised? Is it just because double pointers are hard to read/understand what is happening with a quick glance? Or is it more to do with possible memory problems such as trampling etc?
All of the above.

Pointer arithmetic is extremely error prone, which is why modern C++ tries to distance itself from it. You're doing more C style programming... which there isn't anything wrong with per se... it's just more error prone.

EDIT:

STL containers and algorithms do a very good job at performing common tasks like this. Case in point... using STL... I think I accomplished in 1 line of code what you had to write a loop & a separate function to do.
Last edited on
Topic archived. No new replies allowed.