1

I have written the following replace function which replaces substring inside a big string as follows:

void replace(char *str1, char *str2, int start, int end)
{
    int i,j=0;
    for(i=start; i<end; i++, j++)
        *(str1+i)=*(str2+j);
}

It works fine when I put a string as replace("Move a mountain", "card", 0,4), but when I declare a string using pointer array like char *list[1]={"Move a mountain"} and pass it to the function as replace(list[0], "card",0,4), it gives me a segmentation fault.

Not able to figure it out. Can anybody please explain this to me?

6
  • 3
    Literal strings in C are really read-only arrays of characters. Attempting to modify the contents of such an array leads to undefined behavior. That's why all pointers to literal strings should really be const char *. Commented Feb 11, 2019 at 8:12
  • 6
    On an unrelated note, the expression *(str1+i) is exactly equal to str1[i]. The latter is usually easier to read and understand, as well as little shorter to write. This equivalence is true for all arrays and pointers. Commented Feb 11, 2019 at 8:14
  • I just wonder why the C++ compiler warns about assigning string literals to char* but the C compiler does not. The OP's problem would not have come up had the C compiler also warned about it. Commented Feb 11, 2019 at 8:31
  • 2
    @JoeyMallone In C a literal string is an array of char. In C++ a literal string is an array of const char. The array in C can't be modified though so it effectively is read-only, but it's still not an array of constant characters. This is just one of the way C and C++ differs, and why many here don't like the term "C/C++" or using both C and C++ tags for questions. Commented Feb 11, 2019 at 8:33
  • Related to stackoverflow.com/q/164194/694576. Commented Feb 11, 2019 at 8:44

1 Answer 1

7

The code of function replace looks fine, yet all the ways you call it introduce undefined behaviour:

First, with replace("Move a mountain", "card", 0,4), you are passing a string literal as argument for str1, which is modified in replace then. Modifying a string literal is undefined behaviour, and if it "works", it is just luck (more bad luck than good luck, actually).

Second char *list[1]={"Move a mountain"} is similar but introduces another issue: char*list is an array of pointers, and you initialize list[0] to point to string literal ""Move a mountain". So passing list[0] would again lead to UB due to modifying a string literal. But then you pass list[1], which is out of bounds and therefore introduces undefined behaviour. Again, everything can happen, segfaulting being just one such possibility.

Write

char list[] = "Move a mountain"; // copies string literal into a new and modifiable array 
replace(list, "card",0,4)

and it should work better.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the explanation.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.