3

Is it possible to change a value in a character array initialized by a string pointer this way:

char *word;
word = (char*) malloc(10 * sizeof(char));
word = "Test";
word[2] = 'w';

return 0;

I get a segmentation fault while executing the above code.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 2
    Welcome to Stack Overflow! Warning: You [should not cast](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) the return of malloc. Second warning: when calling `sizeof` in `malloc` (and the like) [you should always write it](http://stackoverflow.com/a/17258659/1151654) as `ptr = malloc(sizeof(*ptr) * ...);` instead of `ptr = malloc(sizeof(ptrtype*) * ...);`. – Eregrith Apr 29 '15 at 14:30
  • 1
    `word = "Test";` assigns the address of the string litteral `"Test"` to `word`, overwriting what you got in there with `malloc` in the first place. You don't seem to know what you are doing at all there and maybe should get a good tutorial or good book on C programming – Eregrith Apr 29 '15 at 14:31
  • You might have to, or you might [search how to do it](https://www.google.fr/search?q=C+change+char+in+string) and then try [what you found is supposed to work](http://stackoverflow.com/questions/9149327/replace-individual-character-element-of-a-string-c). – Eregrith Apr 29 '15 at 14:45

6 Answers6

7

You get a crash because you do this:

word = "Test";
word[2] = 'w';

The first assignment changes the pointer, so it no longer points to the memory you have allocated but to a string literal. And string literals are actually read-only character arrays. And as they are read-only, your attempt of modifying the array in the second assignment will lead to undefined behavior.

The correct way is to copy the string to the memory you have allocated, which you do with the strcpy function:

strcpy(word, "test");

Another thing with the reassigning of the pointer is that you then loose the pointer to the allocated memory, and have a memory leak. You can not call free on the pointer either, since the memory pointed to by word (after your original reassignment) is no longer allocated by you, which would have caused another case of undefined behavior.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Just a last question. If "Test" is a string literal, why can I alter it if the array is declared by the standard array declaration word[]? I want to catch the internal representation of both declarations. –  Apr 29 '15 at 15:25
  • @morophla Because then you create a local array that you can modify like any other local variable. – Some programmer dude Apr 29 '15 at 15:32
  • So the declaration "char word[] = "Test" acts like a strcpy? The string literal is copied at the adress of the first element of the array this way? –  Apr 29 '15 at 16:23
1

Point 1

You don't assign strings after malloc(). Otherwise, you'll be leaking memory. Use strcpy() instead.

Also, please do not cast the return value of malloc() and family.

Point 2

[Without malloc()] string literals (here, "Test") are usually stored in read only memory. Trying to alter them will invoke undefined behaviour.

Ref: As per C11 standard, chapter §6.4.5, string literals, (emphasis mine)

It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

in your code,

word[2] = 'w';

is trying to alter the string literal. And segmentation fault is one of the side effects of UB.

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

There are numerous problems in your code.

  • You should never cast the result of malloc because doing so is pointless and potentially dangerous.
  • In C you copy strings with strcpy(), not with the assignment operator =.
  • Since you never copied the string but just told the pointer to point some place else, you created a memory leak.
  • And since you never copied the string, but are rather just pointing at a string literal, you invoke undefined behavior because you attempt to modify the contents of a string literal. (Remove the malloc line and you'll still have this bug.)
  • You don't seem to free() the memory nor check the return value of malloc.

Correct code:

char* word;
word = malloc(10);
if(word == NULL)
{
  // out of memory, error handling here
}

strcpy(word, "Test");
word[2] = 'w'; // should give "Tewt"
...
free(word);
Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • So you say we should never cast a malloc in C. But in C++ the casting is obligatory right? –  Apr 29 '15 at 17:44
  • @morophla Yes. One of many cases where the languages aren't compatible. It doesn't really matter because you shouldn't be using malloc in C++ anyhow. – Lundin Apr 30 '15 at 06:27
0

It depends. If the pointer pointing to a string literal the you can't. If it is an array of character then it is possible.

In the snippet given, you allocated memory for word using malloc and then you are assigning a string literal to word which let the word point to first character of Test and the previous allocated memory is not pointed by it anymore and it will cause a memory leak. In this case you can't modify Test by word[2] = 'w';. It will invoke undefined behavior.

Instead of word = "Test";, use strcpy to copy string

strcpy(word, "Test");  
haccks
  • 104,019
  • 25
  • 176
  • 264
0

Your code snippet should probably look more like this:

int maxlen = 10;
char *word;
word = malloc(maxlen * sizeof(char));
strncpy(word, "Test", maxlen);
word[2] = 'w';

return 0;
geckon
  • 8,316
  • 4
  • 35
  • 59
  • So while initializing an array like word[] = "Test", does it means the content of the string literal is copied in the array, more or less like strcpy? –  Apr 29 '15 at 17:54
  • @morophia You can do `char word[] = "Test";` which will allocate memory on stack (not on heap) and initializes the char array with the given string. But the string must be known at compile-time. – geckon Apr 30 '15 at 09:17
0

1) the pointer is 'word' is being replaced. That results in a memory leak

2) a literal is in readonly memory, so trying to change anything in that memory results in a seg fault event

user3629249
  • 16,402
  • 1
  • 16
  • 17
  • So while initializing an array like word[] = "Test", does it means the content of the string literal is copied in the array, more or less like strcpy? –  Apr 29 '15 at 17:52