tags:

views:

140

answers:

4

Coincise question: Need to be able to modify contents of char* in c++.

I have a function which is somewhat like this: char* buffer = (char*)FUNCTION

Now I need to modify 'buffer' e.g. do something like this buffer[1] = "h";

Amongst what I have tried is the following: char *string = "Hello World"; char buffer[65]; //I still need to know the exact size strcpy(buffer, string); buffer[1] = "r";

I have tried with malloc also. Unfortunately, the compiler always complain with the following: "cannot convert from const char[2] to char". This occurs on windows. I do not have such a problem with g++ compiler.

I have had a looked at the following links but still I can't do anything. http://www.developerweb.net/forum/archive/index.php/t-3517.html http://stackoverflow.com/questions/752401/about-character-pointers-in-c http://stackoverflow.com/questions/1011455/is-it-possible-to-modify-a-string-of-char-in-c

Thanks

+3  A: 
Svisstack
+1 It's always good to find someone that actually *reads* error messages.
David Rodríguez - dribeas
+4  A: 

You can't change *char string = "Hello World" as string is "read-only" but you can use char string[] = .. which will compiler arrange into modifiable array:

    char * strReadOnly = "read-only-data";
    //strReadOnly [3] = '0'; //access violation 
    char stReadWrite [] = "read-write-data";
    stReadWrite [3] = '0'; // Ok, but just make sure that indexes are in range

To copy string into another buffer that you can change, you can do following:

 char * src = "read-only-data";
 const int len = strlen(src);
 char * dst = new char[len+1];
 strcpy(dst, src); 
 dst[3] = '0'; // ok to change

 delete [] dst; // don't forget to delete dst
sinec
Is it not efficient for me to have to cast the output of my function to char* and then convert this to array? Is there another way out
No, there is no way to change: "char * strReadOnly = "read-only-data";"Please look at @ufotds answer for more info...
sinec
there is no cast. If char* strings, pointers, strcpy and [] syntax are all blowing your mind then consider switching to std::string which will behave the way you probably expect strings to behave.
Kate Gregory
+5  A: 

Since your question is tagged C++, I must question your intentions to be using raw char*s, it's not recommended unless you're very confident.

Secondly, a char* or char[] is perfectly valid to modify. The problem that you've got is that you made a const char* in "Hello World", then tried to make one character in it equal to a string. A character is not a string. "r" is a string, it's a const char*. So you're trying to equate a const char* to a char, which is an error. You really mean 'r', which is a char.

Better code would be:

std::string mystring((char*)FUNCTION); // assume that FUNCTION
                                       // will free it's own memory.
if (index < mystring.size())
    mystring[index] = 'r';
// mystring now cleans up it's own memory in all cases.
DeadMG
+1, even if technically the type of `"r"` is `const char[2]` and not `const char*` §2.13.4[lex.string]/1 *An ordinary string literal has type “array of n const char” and static storage duration*
David Rodríguez - dribeas
+1 for C++ style
sinec
+2  A: 

You have to understand that there is a difference between the following two lines:

char  myArray[] = "Hello Mars!";
char* myPointer = "Hello World!";

The first one creates an array of chars, which can be manipulated. The whole array will be allocated on the stack.

The second one initializes a pointer to char with a string literal (a special construct from the C language allows this). This is to be considered a constant. You will get the address of it, but it is an array of const chars really. The implementation is as follows:

The string will be stored literally in your executable image in memory (as an identical copy of the file on hdd), and you will get the pointer to that string. Space will be made on the stack for the pointer myPointer. Consider the string literal like a literal number in your code (yes, the magic numbers I'm talking about). The compiler needs to store those characters somewhere, but it is not the kind of memory you will normally work with in your program. It is not on the heap, nor on the stack. See the answer to the following question for more info:

http://stackoverflow.com/questions/1169858/global-memory-management-in-c-in-stack-or-heap

edit: about pointers and arrays

It is not the char* that makes it immutable, but the string literal. Pointers and arrays are very much related. An array will very often behave like a pointer. Considering the code above this is completely legal:

myPointer = myArray;

myPointer was not const and you can change it to point to the address of myArray instead of the string literal. The address it pointed to was read-only. Now myPointer points to the adress on the stack where "Hello Mars!" is stored. You could now write:

myPointer[3] = 'Z';

If you want to get a torough understanding of this, read some tutorial like this one.

on constness

Const can be confusing especially with pointers.

const char* const myPointer2 = myPointer;

The first const makes the characters const, so you cannot use myPointer2 to change them, and the second const makes the pointer itself const, so you cannot let it point to something else like myPointer2 = myArray;

See this explanation for more info.

ufotds
Thank you to everyone. I still need to ask you this. I am currently mapping a file to memory. The mapped file is of type char*. I now need to modify the char*. What I do is to copy it to an array and then do modifications on that array. But do I lose efficiency? Is it not better to copy part of the file to an array and then do manipulations.
Ok, maybe you still don't understand it entirely. It is not the char* that makes it constant. It is the string literal "Hello World!". I will elaborate a little more on that above. Regarding the mapped file, I have never used mapped files, but I wonder if it is actually suitable for what you are trying to do. One does not often need mapped files. To me it seems to make sense only if you want to change the file on disk in place. Else just read the parts you need using normal file access methods and then change them without the extra copy. Or ask a new question about it with your code included.
ufotds