c-string vs Strings

Started by
17 comments, last by Oldstench 16 years, 10 months ago
I swear that I think I get it but then I get it all confuzzed A c-string is a collection of characters stored in an array right and C++ places a null terminator at the end of it right? A String type from the String class is different how? I mean I know that itis an object and has member functions and all but does it have a null terminator?

Legal or illegal?
char cString[]= "This is a Cstring";//Legal?
char array[]= "";//Illegal?
String myStr = "Hello GameDev.net members!"//null terminated?

I know that a String type can use .at() to access a Strings elementsso does that mean that it too is an array? Help me, help me please!!1 Show me the lite...........BFX
Advertisement
The C++ string class is std::string (note the lowercase). It does not use a NUL terminator as C-style strings do, it stores the length of the string instead. A C++ string is not an array, but it does implement (like many other classes) a subscript operator. The main difference is that std::string is a first-class object, while C arrays (and strings in particular) are not.
Quote:Original post by bluefox25
A c-string is a collection of characters stored in an array right
and C++ places a null terminator at the end of it right?

Yes. (C also places a null terminator at the end of it though)

Quote:A String type from the String class is different how? I mean I know that itis an object and has member functions and all but does it have a null terminator?

It might or it might not. It doesn't matter because it encapsulates its implementation details. It does, however, store the length of the string as a separate value (which is a much better idea)
You, as the programmer, do not need to use *how* it represents the string, as long as it gives you the functions you need to access it.
In particular, it has the c_str() function which gives you the corresponding C-style string, allowing you to easily convert from one to the other.)

Quote:
I know that a String type can use .at() to access a Strings elementsso does that mean that it too is an array?

It can use .at() or it can use the [] operator, but it's not an array. It just acts a bit like one. But again, the exact implementation don't matter. That's why it's a class. It promises to do what you expect, and you don't need to know exactly *how* it's done.
Great!!
I guess part of the confusion is that sometimes people refer to c-strings as strings so I get confused as to which type they are referring to. Can you initialize a c-string as
char word[]= "";
.

PS
I picked up Beginning Game Programming by Harbour and he tlks about the basics of Windows programming and DirectX. Can I program these two usiing C++, some of his example use C but since I don't know C, I wanna use C++. I like it better than C anyways from of the C code I've seen so far
Quote:Original post by bluefox25 Can you initialize a c-string as *blah*?
Sure. There won't be a whole lot you can do with it, though. I imagine it would just make an array of length one with just a zero in it.

A null terminator is basically just a zero. Nothing more, nothing less. A cstring just lists a bunch of char's, and when you're reading the array and reach a zero, that's the end of the string. So really, the size of the array you allocate when do you something like char * blah = "hi" is actually three, for 'h', 'i', and the number zero.

It's worth nothing what's happening in the program when you do something like char * blah = "Hello!". What's happening is that when you run your program, in the location where your program is in memory, there is your static area of memory. Strings you specify in the middle of your code - anything in "quotes" will be kept in a cstring in this area of memory. So here's the thing - you can't alter this memory. Your program will crash. So -

char * blah = "hello!";
blah[0] = 'H'; // crash

Yeah : )

vvvvvvvvv maybe it's different for if you do char[] or char *. I usually just use char *, and I know then that the pointer you get will be a pointer to static memory. When you do char[] it copies it to the stack? I guess it probably will since an array will take up space for the array right there, where a pointer will just be a pointer. There's still that string in static memory, though, since the program needs to keep that data somewhere.

So! Updatedly;

char blah1[] = "hello!";
blah1[0] = 'H'; // okay?
char * blah2 = "hello!";
blah2[0] = 'H'; // totally crash.]

This distinction isn't entirely relevant to the OP, but it's worth nothing, I guess.

[Edited by - Kimani on May 19, 2007 2:17:31 PM]
Quote:Original post by Kimani
I'll be located in static memory, though, so there's very little you can do with it.


Actually, it would be located in static memory only if the definition is at global scope. It would be located on the stack otherwise. Either way, it's still an array of length 1, so it is not of much use.

Thanks for clearing that up for me.

Another concept I am having a bit of trouble is, visualizing the stack? Is it a function stack? What does thee stack do? Someone said to think of it as a stack of plates but itt still is unclear to me
Quote:Original post by bluefox25
Thanks for clearing that up for me.

Another concept I am having a bit of trouble is, visualizing the stack? Is it a function stack? What does thee stack do? Someone said to think of it as a stack of plates but itt still is unclear to me


Where do variables live? In this function:
void bar( int argument ){    float local;    // ...}

Where in memory are "argument" or "local" stored?

The stack is all about temporary data. This includes all variables you declare inside a function. When you allocate with new, you use a stack variable (the pointer) to remember the address of the heap variable.

int *ptr = new int(42);

ptr is on the stack, the integers address is held in that variable.

However, C++ also needs to use the stack. When you call a function, some or all of the arguments to the function can be placed on the stack. In addition, the "return address" is stored on the stack, so when your function ends or when you use the return statement C++ knows where to resume in the function that called it.

Sharing the stack data with C++'s temporary data can lead to bad things, as I will explain later.

Lets take an example:
void foo( int a ){    char buffer[100];}


On the stack, this would look like:
--------------------------------------------buffer[0]buffer[1]// ...buffer[98]buffer[99]value of areturn address of calling function--------------------------------------------locals for calling codearguments for calling codereturn address for code that called here too--------------------------------------------etc ...retrun address inside main--------------------------------------------main localsmain arguments (argc and argv)return address for main--------------------------------------------


I hope you can see the stack of plates analogy a bit better now. By that we mean, we have a bunch of things piled on top of one another. We can only add a new plate to the top (call another function), or remove the current plate (return from the current function). All the temporary data is stored on the plates, and you can only access data on the plate you are on (although you can cheat around this with pointers an references, but thats the idea anyway). [smile]

Imagine now your code accidentally writes beyond the bounds of an array. With C strings, this is all too easy to do. First of all, you may overwrite the value of the variable "a". If your program tries to use "a" later on it will get wrong results. However, what if your program continues to write and overwrite the return address? When your function finishes, where will it return? Anywhere, depending on the data you overwrite it with (the end of a string, which is often input from the programs user!).

Then a hacker may see this stack layout. They may find that feeding a certain string to part of your program may crash it. Or worse, they may actually construct a special string that returns "inside" itself, or to somewhere else they can write data, allowing them to start executing arbitrary code!

Moral of the story, never use c strings unless you are literally forced too.
I love stories with lessons to be learned.....
So since the main function is the first and last function to be used, are all other function calls and their local variables, "stacked" on top of the main. Is the main function, the largest plate with each function reserved their own plate?

For the life of me, I can't get getline to read a line from my text file:
Isn't that format, getline(readFile,line) where readFile is my ifstream and line is my string
Quote:Original post by bluefox25
I love stories with lessons to be learned.....
So since the main function is the first and last function to be used, are all other function calls and their local variables, "stacked" on top of the main. Is the main function, the largest plate with each function reserved their own plate?

For the life of me, I can't get getline to read a line from my text file:
Isn't that format, getline(readFile,line) where readFile is my ifstream and line is my string


Well, the largest stack frame could be any function that has lots of locals. Most large applications have a pretty short main() function.

Incidentally, this stacking of frames is what allows functions to be recursive. For example:
void recurseTillZero( unsigned i ) {   if( i > 0 ) {       recureTillZero(i - 1);   } else {       std::cout << "got to zero\n";   }}int main( int argc, char **argv ) {    recurseTillZero(3);}

Might have a stack like this:
--------------------------------------------i = 0return address recurseTillZero, line 2--------------------------------------------i = 1return address recurseTillZero, line 2--------------------------------------------i = 2return address recurseTillZero, line 2--------------------------------------------i = 3return address main, line 1--------------------------------------------argv = 1argc = {"myProgramsName.exe"}return address for main--------------------------------------------

What isn't working with std::getline for you? Post compile errors, or example code with the input file and what you expected to output versus what you actually output.

This topic is closed to new replies.

Advertisement