Как интерпретировать эту ошибку отладки - PullRequest
2 голосов
/ 06 апреля 2009

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

#include <stdio.h>
#include <stdlib.h>


char* string_reverse(char* string);

char* string_reverse(char* string) {
  int len = 0;
  for (int i = 0; *(string + i) != '\0'; ++i)
    len++;

  char* result = (char*)malloc(len * sizeof(char));
  if (result == NULL){
    puts("Pointer failure");
    exit(EXIT_FAILURE);
  }

  for (int i = 0; *(string + i) != '\0'; ++i)
    *(result + (len - i)) = *(string + i);

  return *result;
}

int main() {
  char* str= "Ni Hao!";
  char* result = string_reverse(str);

  printf("%s\n", result);
  free(result);
  return 0;
}

В ответ я получаю это сообщение отладки:

Starting program: /home/tmo/string_reverse 

Program received signal SIGSEGV, Segmentation fault.
0xb7e5b3b3 in strlen () from /lib/i686/cmov/libc.so.6

Как мне интерпретировать этот результат?

Ответы [ 2 ]

10 голосов
/ 06 апреля 2009

Ваш код не добавил нулевой терминатор в обратную строку. В результате произошел сбой функции printf при попытке вычислить ее длину.

Измените строку malloc на следующую

char* result = (char*)malloc((len+1) * sizeof(char));

И вам нужно добавить следующую строку в конец функции string_reverse, чтобы строка имела нулевой терминатор.

result[len] = '\0';

Пара других комментариев

  • sizeof (char) не требуется. Размер символа является одним из немногих типов, определенных стандартом C, и его значение равно 1.
  • Первый цикл можно заменить простым вызовом strlen

EDIT

Два других вопроса. Строка, которая на самом деле выполняет копирование символа, кажется неверной. Я считаю, что это должно быть (лен-я-1). В противном случае начальная запись символа будет происходить в (result + len), который является местом нулевого терминатора.

*(result + ((len - i) - 1)) = *(string + i);

Кроме того, не разыменовывайте результат при возврате

4 голосов
/ 06 апреля 2009

Кроме того, вы не должны разыменовывать результат в конце функции, поскольку он уже является указателем на полученную строку.

return result;
...