Нелогичная ошибка шины из printf в C - PullRequest
0 голосов
/ 30 марта 2011

Когда я компилирую и запускаю свой код, я получаю ошибку шины сразу после того, как выдается «запуск».Вот что происходит:

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

Ответы [ 2 ]

4 голосов
/ 30 марта 2011

Если вы определяете строку как:

char *str1 = "apple";

вам не разрешено изменять содержимое - стандарт совершенно ясно, что это неопределенное поведение (a) . Использование:

char str1[] = "apple";

вместо этого, и он даст вам изменяемую копию. Это функционально эквивалентно:

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

(a) C99 6.4.5 "String literals", пункт 6 гласит:

Не определено, различаются ли эти массивы при условии, что их элементы имеют соответствующие значения. Если программа пытается изменить такой массив, поведение не определено.

4 голосов
/ 30 марта 2011

Вы модифицируете строковые литералы, которые часто находятся в постоянной памяти. Стандарт также гласит, что попытка изменить литералы - это неопределенное поведение.

Когда вы используете указатели на строковые литералы, вы должны объявить их как const, const char * str="text"; или как массивы char str[] = "text";

Изменить, например, на:

char str1[] = "apple";

В этом случае компилятор создаст массив в стеке и скопирует в него строковый литерал только для чтения.

...