6

文字列から重複する文字を削除する非常に単純なプログラムを書いています。Visual Studioを実行したところ、エラーが発生しました。

inteviews.exeの0x00d110d9で未処理の例外:0xC0000005:アクセス違反の書き込み場所0x00d27830。

何が問題なのか本当にわかりません。現在のセルは次のセルの値を取得します。

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;
}

編集:

すでにに変更しようとしましたchar str[] = "abcad"が、それでも同じエラーが発生します。

4

3 に答える 3

10

文字列リテラルを変更しようとしています。あなたはそれをすることはできません。

char *str = "abcad";

これは文字列リテラルです。読み取り専用メモリに作成されているため、書き込みを試みるとアクセス違反になります。

于 2011-12-10T18:59:02.527 に答える
6

1つの問題は、読み取り専用の文字列リテラルを作成し、それを変更しようとしたことです。

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

代わりにchar配列を使用できます。

char str[] = "abcad";
于 2011-12-10T19:00:11.827 に答える
3

プログラムにはあらゆる種類の問題があります。それらをすべて書き留めることから始めましたが、コードは取り返しのつかないものだと感じています。インデックス作成エラー、パラメーター受け渡しエラー、疑わしい再帰などがあります。

読み取り専用リテラルを変更しようとするエラーを指摘する他の回答は正しいです。それが、投稿したコードのエラーの原因です。

私の見解では、あなたの問題の主な理由は、バッファが 1 つしかない場合にコードを書くのが難しくなることです。設計でこの制限を回避しようとして苦労しましたが、使用する 2 番目のバッファーがあれば、コードは簡単です。

#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;
}

本当に巧妙になりたい場合は、反復用に 2 つの異なるポインターを保持している限り、実際には 1 つのバッファーだけで問題なく管理できます。

#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;
}

反復によって変更される可能性があるため、バッファ内の最初の文字のコピーを取得する必要があり、その文字は削除されることに注意してください。

これで、単一のバッファーを使用して、開始した場所に戻りました。しかし、コードが機能し、理解しやすくなりました。

私の答えはタグに従ってCで書かれていることに注意してください。ただし、コードはC++であることに注意してください。

于 2011-12-10T19:11:10.327 に答える