Заменить символ в символе [] из функции - PullRequest
1 голос
/ 29 сентября 2011

Как заставить мою функцию replace_char работать правильно?

Способ, которым я пробую это в приведенной ниже функции, возвращает ошибки сегментации с использованием gcc в Ubuntu.

Я пробовал другие способы, но каждый раз, когда я пытаюсь изменить значение, я получаюошибка.

int main (void)
{  
  char* string = "Hello World!";

  printf ("%s\n", string);
  replace_char(string, 10, 'a');
  printf ("%s\n", string);
}

void replace_char(char str[], int n, char c)
{
  str[n] = c;
}

Ответы [ 2 ]

6 голосов
/ 29 сентября 2011

В вашей функции replace_char нет ничего плохого.Проблема в том, что вы пытаетесь изменить строковый литерал («Hello World!»), И это неопределенное поведение.Попробуйте вместо этого создать копию строки, например:

char string[] = "Hello World!";
5 голосов
/ 29 сентября 2011

Редактировать

Чтобы получить «предложение» редактирования string на месте, вы можете отредактировать указатель на месте:

void replace_char(char*& str, int n, char c)
{
  str = strdup(str);
  str[n] = c;
}

int main()
{
    char* string = "Hello World!";
    string = replace_char(string, 10, 'a');

    // ...
    free(string);
}

Примечание Теперь вы должны помнить, чтобы вызвать free в строке после вызова этого.Вместо этого я предлагаю вам сделать то, что я предлагал ранее: заверните литерал в strdup, если это необходимо.Таким образом, вы не несете затрат на выделение копии все время (только когда это необходимо).


Проблема в том, что «Hello World» представляет собой const literal массив символов.

const char* conststr = "Hello World!";
char * string = strdup(conststr);

Я предполагаю, что проблема исчезнет

Объяснение: Компиляторы могут размещать строковые литералы в (только для чтения) сегменте данных.Преобразование в char * (в отличие от const char *) на самом деле недопустимо. Если вы используете, например,

gcc -Wall test.c

, вы получите предупреждение.

Забавный эксперимент:

Обратите внимание, что (поскольку это неопределенное поведение) компиляторы могут делать забавные вещи в таких случаях:

http://ideone.com/C39R6 показывает, что программа не будет «зависать», но молча не удалось изменить строковый литерал, если строка не была скопирована.

YMMV. Используйте -Wall, если хотите, используйте какой-нибудь тип линта и выполните модульное тестирование:) {

...