C — копирование напрямую из памяти с помощью memcpy

Это чисто вопрос домашнего задания, так как я знаю, что вам действительно не следует пытаться сделать это в реальной жизни. Но я пытался сделать это правильно. Скажем, мы знаем постоянную начальную позицию, куда мы хотим скопировать, и точный размер фрагмента памяти, который мы хотим скопировать. Допустим, наш источник — это стек от 0x28000 до 0x2C0000. Стек растет вниз, поэтому нам дан указатель на вершину стека (0x2C0000). Мы хотим скопировать байты STACK_SIZE во второй стек, вершина которого находится на 0x30000. В основном что-то вроде этого:

                Stack 1            Stack 2
       /--+-------------------+-------------------+--/
          |        ABXLQPAOSRJ|                   |
       /--+-------------------+-------------------+--/
      0x280000           0x2C0000            0x300000
                              ^                   ^
                              |                   |
                         Top of stack 1     Top of Stack 2

Если нам придется использовать memcpy, нам придется начинать с 0x28000, верно? (Я не совсем уверен, в каком направлении читает memcpy: от более высокого адреса к более низкому или наоборот) Будет ли это правильным?

void* s = (void *)source_stack_bottom      //where source_stack_bottom is 0x280000 in this case
void* d = (void *)dest_stack_bottom    //which is 0x2C0000
memcpy(d, s, STACK_SIZE)          //STACK_SIZE is just a variable with the stack size

Я не могу понять, почему это не должно работать, но опять же, я все еще довольно смущен тем, как C иногда выделяет память, так что...

РЕДАКТИРОВАТЬ :: К сожалению, переменная путаница. Исправлено сейчас.


person user1777900    schedule 25.01.2013    source источник
comment
Поскольку я знаю, что вам действительно не следует пытаться делать это в реальной жизни - Эммм... почему вы так говорите? Есть много законных причин для копирования блока данных с помощью memcpy. Кто вам это сказал, тот не знает, о чем говорит.   -  person Ed S.    schedule 26.01.2013
comment
С переменными в вашем примере кода произошла забавная история; Я пытался это исправить, но комментарии не совпадали с вызовом memcpy(). Я просто позволю тебе исправить это так, как ты задумал.   -  person Carl Norum    schedule 26.01.2013
comment
Кроме того, не выполняйте приведение возвращаемого значения malloc в C. Вам не нужно приведение, потому что любой тип указателя может быть неявно (и безопасно) преобразован в void*, и это может фактически скрыть ошибку.   -  person Ed S.    schedule 26.01.2013
comment
Ну, это меньше этого и того факта, что мне сказали никогда не делать указатели непосредственно в памяти, потому что вы можете перезаписать что-то важное. Но это имело бы смысл в кодировании ядра (для которого это часть своего рода игрушечной практики).   -  person user1777900    schedule 26.01.2013
comment
@ user1777900: Или обработка изображений, или аппаратный интерфейс ... и т. д. Мы говорим здесь о C, как именно вы предлагаете держаться подальше от указателей?   -  person Ed S.    schedule 26.01.2013


Ответы (2)


Наивная реализация memcpy() будет примерно такой:

void naive_memcpy(void *destt, void *sourcet, size_t size)
{
   char *source = (char *)sourcet;
   char *dest = (char *)destt;
   for(size_t s = 0; s < size; s++){ *dest++ = *source++; }
}

Так что да, счет идет вверх с начала source и dest

person Aniket Inge    schedule 25.01.2013
comment
Кроме разыменования указателей void (что просто не разрешено), что наивного в этом примере? Я думаю, что он отвечает всем требованиям совместимой реализации memcpy(). - person Carl Norum; 26.01.2013
comment
Я бы почти пропустил разыменование void ptr @CarlNorum. Кстати, да, ты прав, ничего наивного в этом нет. - person Aniket Inge; 26.01.2013
comment
Скорее всего, это будет написано в инструкциях, которые используют более крупные копии блоков, если они будут доступны (что будет на современных процессорах). - person Ed S.; 26.01.2013

Да, memcpy() ведет отсчет от базовых адресов, которые вы ему передаете.

Вам вполне может понадобиться сделать что-то подобное, если вы когда-нибудь закончите писать «голое железо» без ОС для встроенных систем или, возможно, если вы сами внедряете операционную систему или ядро.

person Carl Norum    schedule 25.01.2013