Sushant Sushant - 1 month ago 7
C++ Question

Space removal from a String - In Place C style with Pointers

So, its a pretty simple problem and I know the solution which is a simple function like the one below:

void removeSpaces(char* s) {
char* source = s;
char* dest = s;

while(*source) {
if(*source == ' ') {
source++;
} else {
*dest++ = *source++;
}
}

*dest = 0;
}


I am working in Visual C++ 2008 Express edition

When I call it with the following it works fine without any issues i.e it removes all the spaces:

int main() {
char input[50] = "I like 2% milk";
removeSpaces(input);
cout<<input;

getchar();
return 0;
}


But, the problem is when I call it by changing the string declaration to this:

char * input = "I like 2% milk";


I get a exception (some kind of access violation)

The exception is showing on this line of code of the removeSpace function

*dest++ = *source++;


Can anyone elaborate as to why is this happening?

Answer

When you do

char* something = "a string literal";

The compiler puts "a string literal" into the executable image itself and just assigns a pointer to this memory to something. You are not allowed to modify this memory, and many times the memory that the string resides in is marked read-only, so any attempts to write to it result in an access violation like the one you experienced.

When you do

char something[] = "a string literal";

you are really creating an array on the stack named something and initialising it with "a string literal". This is equivalent of doing char something[] = {'a', ' ', 's', 't', 'r', ..., 'a', 'l', 0};. Since this memory is on the stack, you can modify it freely.

char* something = "a string literal" looks like

    stack                              executable

-------------                     ---------------------
|~~~~~~~~~~~|                     | ~~~~~~~~~~~~~~~~~ |
| something | ----------------->  | a string literal0 |
-------------                     | ~~~~~~~~~~~~~~~~~ |
                                  ---------------------

Whereas char something[] = "a string literal" looks like

stack

-----
|~~~|
| a |  <- something is an alias for this location
|   |
| s |
| t |
| r |
| i |
| n |
| g |
|   |
| l |
| i |
| t |
| e |
| r |
| a |
| l |
| 0 |
-----

Where ~~~ means "other memory etc".

Note that

char* x = "string literal";

Is actually invalid and should not compile because you cannot convert a char const[x] to a char*. It should be const char* x, not char* x, but some old and non-conformant compilers wrongly allow this behaviour.