Memcpy копирование частично над собой - PullRequest
5 голосов
/ 15 марта 2011

Это нормально?

char buf[] = { 0, 1, 2 };
memcpy(buf, buf + 1, 2);

Имеет ли значение тип данных большего размера?Я знаю, что могу использовать memmove (), но мне просто любопытно.

Ответы [ 4 ]

12 голосов
/ 15 марта 2011

Эффекты memcpy не определяются, когда вход и выход перекрываются. Вы должны использовать memmove.

5 голосов
/ 15 марта 2011

Не в порядке. Вы должны использовать memmove, когда источник и пункт назначения перекрываются.

Это может работать с memcpy, в зависимости от реализации вашего компилятора, но на это не стоит полагаться!


Типичная наивная реализация может быть побайтной копией (uint8), например:

typedef unsigned char uint8;

void * memcpy ( void * destination, const void * source, size_t num )
{
    const uint8* pSrc = (const uint8*)source;
    const uint8* const pSrcEnd = pSrc + num;
    uint8* pDst = (uint8*)destination;

    while (pSrc != pSrcEnd)
        *(pDst++) = *(pSrc++);

    return destination;
}

, который будет работать нормально с вашим memcpy(buf, buf + 1, 2), но не так хорошо с memcpy(buf + 1, buf, 2)

3 голосов
/ 15 марта 2011

Поведение не определено, если области памяти перекрываются, поэтому это не нормально.

1 голос
/ 15 марта 2011

Это неопределенное поведение, но я использовал его так,

char buf[] = {0, 1, 2, 3);
memcpy(buf, buf+2, 2);

, где конечная точка пункта назначения меньше начальной точки источника. Вы должны все еще использовать memmove, чтобы быть уверенным ...

...