memmove, memcpy и new - PullRequest
       44

memmove, memcpy и new

3 голосов
/ 10 марта 2010

Я делаю простой байтовый буфер, который хранит свои данные в массиве char, полученном с помощью new, и мне просто интересно, будут ли функции memcpy и memmove показывать мне что-нибудь странное, если использовать их с памятью, полученной с помощью new, или есть что-нибудь, что вы бы сделали рекомендовать делать вместо этого?

Ответы [ 5 ]

4 голосов
/ 10 марта 2010

Использование memcpy() / memmove() должно нормально работать с такими данными. В общем, вы можете безопасно использовать их на любом типе POD.

3 голосов
/ 10 марта 2010

Нет, они в порядке. new и malloc() - это всего лишь два разных способа получения памяти в куче (на самом деле они совершенно одинаковы, поскольку new использует malloc() под капотом в большинстве реализаций). Как только у вас в руке будет действительная переменная char* (выделенная new, malloc() или в стеке), это просто указатель на память, поэтому memcpy() и другие функции из этого семейства будут работать как ожидается.

2 голосов
/ 10 марта 2010

Для данных массива char он должен работать нормально даже в сочетании с новым.

Но в C ++ почему бы не использовать std :: copy или std :: copy_backward и полностью устранить вопрос?

1 голос
/ 10 марта 2010

Это на самом деле зависит от вашей платформы и реализации вашего компилятора new и memmove. Большинство процессорных архитектур лучше перемешивают данные, когда они выровнены по границам слов, но у некоторых есть дополнительные случаи, когда они работают лучше. Например, PowerPC 7447 работает быстрее всего с памятью, выровненной по границам 16 байт . Это размер векторных регистров для его набора команд Altivec SIMD, так что memcpy или аналогичная функция может быть реализована намного быстрее для массивов, которые расположены на границах 16 байтов. См. этот вопрос для примера.

Почему это имеет значение для новых? Поскольку новый оператор может хранить некоторые метаданные о выделенном блоке памяти в паре байтов перед указателем, который он возвращает, то фактический указатель, который он вам дает, представляет собой слово или два после фактического начала выделения. На процессоре, ОС и компиляторе, где я столкнулся с этим поведением (PowerPC 7447a, VxWorks 5.5, GCC 2.95), новый оператор гарантированно предоставил вам блоки, которые были выровнены на 8 байтов, но не выровнены на 16 байтов. Это, конечно, очень зависит от реализации. Я не верю, что в стандарте C ++ есть что-то, что определяет выравнивание, поскольку это будет оптимизация для конкретной архитектуры.

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

0 голосов
/ 10 марта 2010

Я бы все еще использовал vector с std :: copy, но это не значит, что new / memcpy / memmove - это плохо. memmove на самом деле предпочтительнее, если вы настаиваете на перемещении частей в буфере.

...