2

私は、C 文字列 (char*) を操作するためのいくつかの基本的な関数を作成するために、malloc、realloc、および free をいじっています。文字列から最後の文字を消去するときに、この奇妙な問題が発生しました。私はそのようなプロトタイプで関数を書きました:

int string_erase_end (char ** dst, size_t size);

「dst」文字列を1文字短くすることになっています。これまでのところ、私はこのコードを思いつきました:

int string_erase_end (char ** dst, size_t size)
{
    size_t s = strlen(*dst) - size;
    char * tmp = NULL;
    if (s < 0) return (-1);
    if (size == 0) return 0;
    tmp = (char*)malloc(s);
    if (tmp == NULL) return (-1);
    strncpy(tmp,*dst,s);
    free(*dst);
    *dst = (char*)malloc(s+1);
    if (*dst == NULL) return (-1);
    strncpy(*dst,tmp,s);
    *dst[s] = '\0';
    free(tmp);
    return 0;
}

main() で、文字列を切り詰めると (以前に malloc を呼び出しました)、奇妙な結果が得られます。切り捨てたい文字数に応じて、正常に機能するか、間違った数の文字が切り捨てられるか、セグメンテーション違反がスローされます。

私は動的メモリ割り当ての経験がなく、常に C++ とその std::string を使用してそのような汚い作業をすべて行ってきましたが、今回は C でこれを行う必要があります。ここで間違い。前もって感謝します。

4

3 に答える 3

2

最初のstrncpy()は、tmpの最後に「\0」を付けません。

また、二重コピーを回避することもできます。* dst = tmp;

于 2010-01-06T13:44:52.823 に答える
2

あなたの説明によると、あなたの関数は文字列の最後の n 文字を消去することになっています:

/* Assumes passed string is zero terminated... */
void string_erase_last_char(char * src, int num_chars_to_erase)
{
    size_t len = strlen(src);

    if (num_chars_to_erase > len)
    {
        num_chars_to_erase = len;
    }

    src[len - num_chars_to_erase] = '\0';
} 
于 2010-01-06T13:43:12.093 に答える
1

sizeパラメータの目的がわかりません。

文字列が最初にを使用して割り当てられている場合はmalloc()、を使用realloc()してサイズを変更する必要があります。これにより、コンテンツが自動的に保持され、必要な操作が少なくなります。

int string_erase_end (char ** dst)
{
  size_t len;
  char *ns;

  if (dst == NULL || *dst == NULL)
   return -1;

  len = strlen(*dst);
  if (len == 0)
    return -1;

  ns = realloc(*dst, len - 1);
  if (ns == NULL)
   return -1;
  ns[len - 1] = '\0';
  *dst = ns;

  return 0;
}

「現実の世界」では、通常、1文字の切り捨てに割り当てられたサイズを変更することはありません。非効率的すぎます。代わりに、文字列の長さと割り当てられたサイズを別々に追跡します。これにより、文字列が簡単に成長します。すでにスペースが割り当てられている限り、文字を追加するのは非常に高速です。

malloc()また、Cでは、 ;の戻り値をキャストする必要はありません。それは目的を果たさず、バグを隠すことができるので、それをしないでください。

于 2010-01-06T13:44:22.390 に答える