Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access violation writing location when working with pointers to char

I am writing a very simple program that removes duplicate chars from a string. I ran it visual studio and got the error:

Unhandled exception at 0x00d110d9 in inteviews.exe: 0xC0000005: Access violation writing location 0x00d27830.

I really don't see what the problem is. current cell gets the value of the next cell.

void remove(char *str, char a) {
    while (*str != '\0') {
        if (*(str+1) == a) {
            remove(str + 1, a);
        }

        *str = *(str +1 );//HERE I GET THE ERROR
        ++str;
    }
}


int _tmain(int argc, _TCHAR* argv[])
{
    char *str = "abcad";

    while (*str != '\0') {
        remove(str,*str);
        str++;
    }

    std::cout << str << std::endl;

    return 0;
}

EDIT:

I already tried to change it to char str[] = "abcad" but I still get the same error.

like image 420
Asher Saban Avatar asked Dec 10 '11 18:12

Asher Saban


3 Answers

You're attempting to modify a string literal. You can't do that.

char *str = "abcad";

That's a string literal. It's created in read-only memory therefore attempting to write to it is an access violation.

like image 63
Brian Roach Avatar answered Sep 19 '22 00:09

Brian Roach


One problem is that you created a read-only string literal and attempted to modify it:

char *str = "abcad"; // String literals are read-only!

You could use a char array instead:

char str[] = "abcad";
like image 29
Mark Byers Avatar answered Sep 21 '22 00:09

Mark Byers


There are all sorts of problems with your program. I begun by trying to write them all down but I feel that code is irredeemable. It has indexing errors, parameter passing errors, dubious recursion and so on.

The other answers that point out the error of trying to modify a read-only literal are correct. That is the cause of the error in the code you posted.

The main reason for your troubles, in my view, is that the code is harder to write when you only have a single buffer. You have tied yourself in knots trying to get around this limitation in your design, but with a second buffer to work with, the code is trivial.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    const char *input = "abcad";
    char *output = malloc(strlen(input)+1);

    char *in = input;
    char *out = output;
    while (*in)
    {
        if (*in != input[0])
        {
            *out = *in;
            out++;
        }
        in++;
    }
    *out = '\0';

    printf("%s\n", output);

    free(output);

    return 0;
}

If you want to get really clever you can in fact manage happily with just a single buffer, so long as you keep two distinct pointers for iteration.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char str[] = "abcad";
    char compare = str[0];

    char *in = str;
    char *out = str;
    while (*in)
    {
        if (*in != compare)
        {
            *out = *in;
            out++;
        }
        in++;
    }
    *out = '\0';

    printf("%s\n", str);

    return 0;
}

Note that we had to take a copy of first character in the buffer, the character being removed, since that may be modified by the iteration.

So now you are back where you started, with a single buffer. But now the code works and is easy to understand.

Note that my answer is written in C as per your tag, but note that your code is C++.

like image 32
David Heffernan Avatar answered Sep 21 '22 00:09

David Heffernan