Подскажите, пожалуйста, что не так с этой функцией обращения строк? - PullRequest
0 голосов
/ 27 марта 2010

Этот код компилируется чисто. Но когда я запускаю это, он выдает исключение «Место записи нарушения доступа» в строке 9.

void reverse(char *word)
{
int len = strlen(word);
len = len-1;
char * temp= word;
int i =0;
while (len >=0)
{
word[i] = temp[len];  //line9
++i;--len;
}
word[i] = '\0';
}

Ответы [ 7 ]

7 голосов
/ 27 марта 2010

Вы проходили этот код в отладчике?

Если нет, что произойдет, когда i (возрастание от 0) пройдет len (уменьшится в сторону 0)?

Обратите внимание, что два ваших указателя word и temp имеют одинаковое значение - они указывают на одну и ту же строку.

4 голосов
/ 27 марта 2010

Будьте осторожны: не все строки в программе на C ++ доступны для записи. Даже если ваш код хорош, он все равно может потерпеть крах, когда кто-то вызывает его со строковым литералом.

3 голосов
/ 27 марта 2010

Когда len достигает 0, вы получаете доступ к местоположению до начала строки (temp[0-1]).

2 голосов
/ 27 марта 2010

Попробуйте это:

void reverse(char *word)
{
  size_t len = strlen(word);
  size_t i;

  for (i = 0; i < len / 2; i++)
    {
      char temp = word[i];
      word[i] = word[len - i - 1];
      word[len - i - 1] = temp;
    }
}
1 голос
/ 27 марта 2010

Функция выглядит так, как будто она не будет аварийно завершать работу, но она не будет работать правильно, и она будет читать из слова [-1], что вряд ли приведет к аварийному завершению, но это проблема. Возможно, ваша проблема с аварийным завершением состоит в том, что вы передали строковый литерал, который компилятор поместил в сегмент данных только для чтения.

Нечто подобное может произойти сбой во многих операционных системах.

char * word = "test";
reverse(word); // this will crash if "test" isn't in writable memory

Есть также несколько проблем с вашим алгоритмом. У вас есть len = len-1, а затем temp[len-1], что означает, что последний символ никогда не будет прочитан, а когда len == 0, вы будете читать с первого символа до слова. Кроме того, temp и word оба являются указателями, поэтому они оба указывают на одну и ту же память, я думаю, вы хотели создать копию слова, а не просто копию указателя на слово. Вы можете сделать копию word с помощью strdup . Если вы сделаете это и исправите свою проблему с len, то ваша функция должна работать,

Но это по-прежнему не исправит сбой записи, вызванный кодом, который вы нам не показали.

О, и если вы используете strdup, обязательно вызовите free, чтобы освободить temp, прежде чем покинуть функцию.

0 голосов
/ 27 марта 2010

Если вы вызвали эту функцию следующим образом:

reverse("this is a test");

тогда хотя бы с одним компилятором передаст строку только для чтения из-за обратной совместимости с C, где вы можете передать строковые литералы как неконстантный символ *.

0 голосов
/ 27 марта 2010

Ну, к примеру, когда len == 0 len-1 будет отрицательным числом. И это довольно незаконно. Во-вторых, вполне возможно, что ваш указатель указывает на незарезервированную область памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...