-2

C function copies string to the same string but any repeated characters ':' replaced with one, but why there is 'Exception write access':

void shiftStr(char* str)
{
    int len = strlen(str);
    int c = 0;
    int n1 = 0;
    int j = 0;
    std::cout << "string0:" << str << "\n";
    for (int i = 0; i < len; i++)
    {
        if (str[i] == ':')
            n1++;
        else
            n1 = 0;
        if (n1 > 1)
            continue;

        str[j] = str[i];//<-----------Exception write access
        j++;
    }
    std::cout << "string1:" << str << "\n";
}

int main()
{
    char* str = (char*)"a:z::bb:::cc::::";
    shiftStr(str);
}
SergeyA
  • 61,605
  • 5
  • 78
  • 137
ZedZip
  • 5,794
  • 15
  • 66
  • 119
  • 1
    That code isn't C, it's C++. And please create a [mcve] to show us, especially how you call the function and what you pass for argument. – Some programmer dude Feb 11 '19 at 14:54
  • 2
    And unless it's a requirement for an exercise, please don't use `char` arrays or similar for strings. Use a proper `std::string` object instead. It will make your life as a C++ programmer much simpler. – Some programmer dude Feb 11 '19 at 14:55
  • 2
    Most likely you didn't allocate any memory to store the string. Or you are trying to write to a string literal. Impossible to tell since the bug is in the caller code. – Lundin Feb 11 '19 at 14:56
  • The compiler tried to stop you from writing buggy code. You hit it over the head with `(char*)"a:z::bb:::cc::::";` – StoryTeller - Unslander Monica Feb 11 '19 at 15:01
  • Ah, I am trying to write to the literal. Yes, Lundin, thnx – ZedZip Feb 11 '19 at 15:01
  • 2
    Possible duplicate of [Why do I get a segmentation fault when writing to a string initialized with "char \*s" but not "char s\[\]"?](https://stackoverflow.com/questions/164194/why-do-i-get-a-segmentation-fault-when-writing-to-a-string-initialized-with-cha) – Jabberwocky Feb 11 '19 at 15:02
  • As a general tip: Whenever you do a C-style cast in C++, it's a red flag and a sign that you probably do something wrong. – Some programmer dude Feb 12 '19 at 06:42

1 Answers1

3

String literals are read-only. You are casting your "a:z::bb:::cc::::" literal to a (char*), which will hide your error. Replace that line with const char *str = (const char *)"a:z::bb:::cc::::" and your compiler will complain.

To solve this error, move your string from read-only memory to the stack:

char str[] = "a:z::bb:::cc::::" // The string literal is stored as an array on the stack (don't make it too big!)

yyny
  • 1,623
  • 18
  • 20
  • Not quite, string literals are not read-only, but modifying them is _undefined behaviour_. But yes often they are actually read-only and trying to modify them raises an exception (segfault, address error etc.) – Jabberwocky Feb 11 '19 at 15:05
  • 1
    @Jabberwocky They are read-only in C++ but not in C. Writing to them is UB in either language. – Lundin Feb 11 '19 at 15:06
  • @Jabberwocky, in C++ type of the string literal is `const char[]` - which makes it read-only in laymen terms. – SergeyA Feb 11 '19 at 15:12
  • 1
    @Jabberwocky I would argue that writing to a const is not UB, as it is well defined as illegal. – Michael Surette Feb 11 '19 at 15:40