String variables... why?

I have been wondering why is it that we have a "string" type when we could easily say char * variable = "string";.

I have arrived to some conclusions with a friend while testing upon it, like for example, assigning something different to that pointer would not use the same memory address and basically it would be bad memory management because that memory would be released only after the program is closed.

But now I would like to hear some of you experienced people out there explaining why is it bad to do that, and instead we should use the "string" type or a char array (I have an understanding that under the hood it is the same thing).

I hope you guys understood the question.
And here is some code that we tested out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <stdio.h>
using namespace std;

void pause()
{
        cout << "\nPress <Enter> to continue...";
        cin.sync();
        cin.ignore();
}

int main()
{
        char * x;
        char * y;
        char * terry = "hello";
        x = terry;
        printf("terry: %i ", terry);
        terry = "what is wrong with this world?";
        y = terry;
        printf("terry: %i \n", terry);
        printf(x); printf("\n"); printf(y);
        pause();
        return (0);
}



The correct syntax is:

 
const char* variable = "string";


Because the contents of the string pointed to by variable are not changeable. Note however that variable can be made to point to a different string by simply reassigning the pointer. Literal strings are compiled into the executable and are effective part of the program's code; there is no need or ability to free such memory.

Now, however, if you wanted to modify the string pointed to, then you have to use dynamic memory allocation, copy the string into the new buffer, modify it, and remember to free the memory when done with it.

std::string makes the task of string manipulation easier (one can simply "add" two strings together to concatenate). std::string also rids you of having to allocate the memory, reallocate it to make the string bigger, and free it when you're done--std::string does all this for you.

closed account (3hM2Nwbp)
First and foremost, imo is convenience.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<string> //std::string
#include<iostream>
#include<string.h> // CString
int main()
{
  { /* std::string */
    std::string first = "First";
    std::string second = "Second";
    std::cout << (first + second)<< std::endl;
  }
 
  { /* C-Strings */
    const char* first = "First";
    const char* second = "Second";
    char* together = new char[strlen(first) + strlen(second)];
    strcat(together, first);
    strcat(together, second);
    std::cout << together << std::endl;
    delete[] together;
  }
  return 0;
}


* Too late :(
Last edited on
Well for starters, char* foo = "bar"; technically isn't legal, even though many compilers allow it (they allow it only to be compatible with legacy code. You should never do that in new code). string literals are constant so you'd have to do const char* foo = "bar";.

That said.... it has to do with memory management.

a pointer just points to memory that exists somewhere else. When you do this:

 
const char* foo = "bar";


What's happening is the compiler keeps a constant string literal in the program somewhere (think: in the exe itself), and you create a variable named foo that points to that memory.

Conversely, using a char array does something quite different:

 
char foo[20] = "bar";


Instead of just pointing to existing memory, this allocates a new block of memory (20 chars big) and copies the "bar" string to that block of memory.

Now since this is actual modifiable memory and not merely pointing to strings that exist elsewhere, we can mess with the string data:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char foo[20] = "bar";

cout << foo;  // prints "bar"

foo[0] = 'f'; // OK to modify foo

cout << foo;  // prints "far"

foo[2] = 'b';

cout << foo;  // prints "fab"

strcat(foo,"ulous");  // append "ulous" to foo

cout << foo;  // prints "fabulous" 


None of that will work if you're pointing to a constant string literal like you would if you're using a const char*

Let's take another example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// assuming this works (even though it shouldn't!)
char* a = "test";
char* b = "test";

/* at this point, a and b both point to some memory in the exe that holds the string "test"
  now rather than repeat "test" in the exe multiple times, the compiler will probably just make
  a and b point to the same block of memory.

 Similar to if you did this:

char memory[20] = "test";
char* a = memory;
char* b = memory;
*/

//also assuming this will work (even though it shouldn't):
a[0] = 'b';

cout << a; // we would expect this to print "best" (even though it might not)

cout << b; // but what about this? 


We didn't change 'b' in that code, so you'd think it would print "test"... but it might not. If a and b indeed point to the same memory, and we modified that memory through a, then printing b is the same as printing a, in which case we'd get "best" instead of "test".



So basically:

- pointers just point to data that exists elsewhere
- char arrays actually hold the data themselves, they don't reference external memory


The string class is basically the exact same thing as a char array, only easier and safer to use since it can resize the buffer as needed (so you don't have to worry about overflowing string data past the end of what you allocated).


EDIT: doh I'm way too slow
Last edited on
Topic archived. No new replies allowed.