-9

関数は strcpy として機能するはずですが、別の関数で使用できる文字列を使用することを理解しているため、独自の strdup 関数を作成しようとしましたが、プロトタイプでは、文字がコピーされない理由がわかりません。

このプロトタイプを作成しましたが、関数が返すポインターが文字列を表示しない理由がわかりません

char            *my_strdup(char *str)
{
  char          *new_str;
  char          *to_copy;
  int           i;

  to_copy = str;
  i = strlen(str + 1);
  new_str = malloc(sizeof(*new_str) * i + 1);
  while(i - 1 > 0)
    {
      *new_str = *to_copy;
      new_str++;
      to_copy++;
      i--;
    }
  return(new_str);
}

ここに私のテスト機能があります:

int             main()
{
  char          *str;

  str = my_strdup("helloo");
  printf("%s\n", str);
}
4

1 に答える 1

6

文字列の先頭ではなく、文字列の末尾へのポインターを返しています。

与えたポインタを返す必要がありmallocます。それはnew_str、あなたが への最初の割り当てで入れたものですnew_str。ただし、それを返す代わりに、そのポインターを変更してから返します。

コードには他にも多くの問題があります。たとえば、この時点で:

i = strlen(str + 1);

で始まる文字列の長さを計算しますstr[1]。文字列の長さがゼロの場合、未定義の動作が発生します。

おそらく、あなたは次のように書くつもりでした:

i = strlen(str) + 1;

その場合、あなたの呼び出しmallocは割り当てが多すぎます。

sizeof(*new_str)と等しいことが保証されているため、使用しても意味がありません1

とにかく、コードを修正しようとするのではなく、いくつかの可能な代替手段を以下に示します。

char *mystrdup(const char *str)
{
    char *result = malloc(strlen(str) + 1);
    char *psrc = str;
    char *pdst = result;
    while (*psrc != 0)
    {
        *pdst = *psrc;
        pdst++;
        psrc++;
    }
    *pdst = '\0';
    return result;
}

次のように、ループの本体をより簡潔にすることができます。

*pdst++ = *psrc++;

forループでそれを行うことができます:

char *mystrdup(const char *str)
{
    size_t len = strlen(str);
    char *result = malloc(len + 1);
    for (size_t i = 0; i <= len; i++)
        result[i] = str[i];
    return result;
}

memcpyまたは、次のように使用することもできます。

char *mystrdup(const char *str)
{
    size_t len = strlen(str);
    char *result = malloc(len + 1);
    memcpy(result, str, len + 1);
    return result;
}

すべての場合において、返される値は変更されずに返されることに注意してくださいmalloc

malloc の呼び出しで発生する可能性のあるエラー状態を無視しました。あなたはそれについて心配することができます!

于 2013-09-18T12:59:02.897 に答える