0

以下のコードスニペットは、の実装を示していますmemmove()

void my_memmove(void* dest, const void* src, size_t size)
{
    unsigned int i;

    char* d = (char*)dest;
    char* s = (char*)src;

    if( s > d )
    {
            for( i = 0; s[i] && i < size; ++i )
                    d[i] = s[i];
    }
    else
            for( i = size-1; d[i] && i >= 0; --i )
                    d[i] = s[i];
}

int main()
{
    char my_str[] = "abcdefgh";

    char str[] = "abcdefgh";

    my_memmove(my_str+1, my_str, 4);

    memmove(str+1, str, 4);

    printf("%s %s\n", my_str, str);

    return 0;
}

私は次のように出力を取得しています:

 aabcdfgh  

my_memmove()が正しく機能しないのはなぜですか(空の文字列を出力するようにmy_strを変更します)?

4

2 に答える 2

5

符号なし整数の場合、条件i >= 0は常に真です。「-1」の反転バイアスを使用して慣用的なループを作成することをお勧めします。

for (i = 0; i != size; ++i)
    d[size - i - 1] = s[size - i - 1];

また、追加の条件s[i] &&は明らかに間違っているように見えます。

于 2012-08-20T13:09:00.510 に答える
1

srcとdestが同じメモリブロック内のポイントを指していると想定しています。

...
char* d = (char*)dest;
char* s = (char*)src;

if( s > d )
...

これは、誰かがsrcとdestを使用して関数を呼び出し、メモリ内の2つの異なる場所を指している場合、未定義の動作が発生することを意味します。

これは非常に悪いことです。組み込みのmemmove()を使用するだけです。

于 2013-01-29T05:21:41.630 に答える