Is it ok to mix cstrings and strings?

Nov 12, 2013 at 6:00pm
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
Nov 12, 2013 at 6:14pm
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";

Nov 12, 2013 at 6:20pm
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 Nov 12, 2013 at 6:22pm
Nov 12, 2013 at 6:39pm
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?
Nov 12, 2013 at 6:42pm
Can I have as much control with std::string as with normal cstrings?

What do you mean, when you say "control"?
Nov 12, 2013 at 6:44pm
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.
Nov 12, 2013 at 6:57pm
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?
Nov 12, 2013 at 7:18pm
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 Nov 12, 2013 at 7:21pm
Nov 12, 2013 at 7:22pm
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?
Nov 12, 2013 at 7:26pm
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 Nov 12, 2013 at 7:29pm
Topic archived. No new replies allowed.