2

トレーニング中のハッカーとして、文字列を受け取り、新しい文字列にメモリを割り当て、新しい文字列へのポインターを返す独自の 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

この結果をどのように解釈すればよいでしょうか?

4

2 に答える 2

10

あなたのコードは、反転された文字列にヌル ターミネータを追加しませんでした。その結果、その長さを計算しようとして printf 関数がクラッシュしました。

malloc 行を次のように変更します。

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

また、string_reverse 関数の末尾に次の行を追加して、文字列に null ターミネータが含まれるようにする必要があります。

result[len] = '\0';

他のいくつかのコメント

  • sizeof(char) は必要ありません。char のサイズは C 標準で定義されている数少ない型の 1 つで、値は 1 です。
  • 最初のループは、strlen への単純な呼び出しに置き換えることができます

編集

他の2つの問題。実際に文字コピーを行う行が間違っているようです。(len - i - 1) であるべきだと思います。それ以外の場合、最初の文字書き込みは、null ターミネータの場所である (result + len) で発生します。

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

また、戻り時に結果を逆参照しないでください

于 2009-04-06T01:43:46.603 に答える
4

また、結果の文字列へのポインターが既にあるため、関数の最後で結果を逆参照しないでください。

return result;
于 2009-04-06T01:49:22.690 に答える