0

コードをコンパイルして実行すると、「starting」と出力された直後にバスエラーが発生します。これが何が起こるかです:

bash-3.2$./remDup
開始
バスエラー

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

void removeDups(char* str) 
{
    int len = strlen(str);
    int i = 0;

    for (i = 0; i < len; i++) {
        char a = str[i];
        int k = i + 1;
        int c = 0;
        int j = 0;

        for (j = k; j < len; j++) {
            if (a != str[j]) {
                str[k] = str[j];
                k++;
            } else c++;
        }

        len -= c;
    }

    str[len] = '\0';
}

int main(int argc, const char* argv[] )
{
    char *str1 = "apple";

    printf("%s -> ", str1);
    removeDups(str1);
    printf("%s\n ", str1);

    return 1;
}
4

2 に答える 2

4

多くの場合、読み取り専用メモリに存在する文字列リテラルを変更しています。規格はまた、リテラルを変更しようとすることは未定義の動作であると述べています。

文字列リテラルへのポインタを使用している場合は、それらをconstconst char * str="text";または配列として宣言する必要がありますchar str[] = "text";

たとえば、次のように変更します。

char str1[] = "apple";

この場合、コンパイラはスタック上に配列を作成し、読み取り専用の文字列リテラルをその配列にコピーします。

于 2011-03-30T08:25:36.087 に答える
4

文字列を次のように定義する場合:

char *str1 = "apple";

内容を変更することは許可されていません。標準では、これが未定義の動作であることは明らかです(a)。使用する:

char str1[] = "apple";

代わりに、変更可能なコピーが提供されます。機能的には次のものと同等です。

char str1[6]; strcpy (str1, "apple");

(a) C99 6.4.5 "String literals"、段落は次のように6述べています。

それらの要素が適切な値を持っている場合、これらの配列が別個であるかどうかは指定されていません。プログラムがそのような配列を変更しようとした場合、動作は未定義です。

于 2011-03-30T08:25:45.967 に答える