C-使用memcpy直接从内存复制
这纯粹是一个家庭作业问题,因为我知道你真的不应该在现实生活中这样做。但我一直在努力把这件事做好。假设我们知道要复制的永久起始位置以及要复制的内存块的确切大小。假设我们的源是一个从0x28000到0x2C0000的堆栈。堆栈向下增长,因此我们得到一个指向堆栈顶部的指针(0x2C0000)。我们希望将堆栈大小字节复制到第二个堆栈,其顶部为0x30000。基本上是这样的:C-使用memcpy直接从内存复制,c,memory,memcpy,C,Memory,Memcpy,这纯粹是一个家庭作业问题,因为我知道你真的不应该在现实生活中这样做。但我一直在努力把这件事做好。假设我们知道要复制的永久起始位置以及要复制的内存块的确切大小。假设我们的源是一个从0x28000到0x2C0000的堆栈。堆栈向下增长,因此我们得到一个指向堆栈顶部的指针(0x2C0000)。我们希望将堆栈大小字节复制到第二个堆栈,其顶部为0x30000。基本上是这样的: Stack 1 Stack 2 /--+-----------
Stack 1 Stack 2
/--+-------------------+-------------------+--/
| ABXLQPAOSRJ| |
/--+-------------------+-------------------+--/
0x280000 0x2C0000 0x300000
^ ^
| |
Top of stack 1 Top of Stack 2
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++; }
}
如果我们必须使用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有时是如何分配内存的,所以
编辑::Oops,变量混淆。现已修复。是,memcpy()
从传递给它的基地址开始计算
如果您最终为嵌入式系统编写“裸机”类的无操作系统软件,或者您自己正在实现操作系统或内核,那么您可能非常需要这样做。是的,memcpy()
从传递给它的基地址开始计算
如果您最终为嵌入式系统编写“裸机”类的无操作系统软件,或者您自己正在实现操作系统或内核,那么您可能非常需要这样做。一个简单的
memcpy()
实现应该是这样的:
Stack 1 Stack 2
/--+-------------------+-------------------+--/
| ABXLQPAOSRJ| |
/--+-------------------+-------------------+--/
0x280000 0x2C0000 0x300000
^ ^
| |
Top of stack 1 Top of Stack 2
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++; }
}
void naive\u memcpy(void*dest,void*sourcet,size\u t size)
{
char*source=(char*)sourcet;
char*dest=(char*)dest;
对于(size_t s=0;s
是的,它从
source
和dest
开始向上计数memcpy()
的简单实现如下:
Stack 1 Stack 2
/--+-------------------+-------------------+--/
| ABXLQPAOSRJ| |
/--+-------------------+-------------------+--/
0x280000 0x2C0000 0x300000
^ ^
| |
Top of stack 1 Top of Stack 2
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++; }
}
void naive\u memcpy(void*dest,void*sourcet,size\u t size)
{
char*source=(char*)sourcet;
char*dest=(char*)dest;
对于(size_t s=0;s
是的,它从
source
和dest
开始向上计数,“因为我知道你真的不应该在现实生活中这样做”-嗯。。。你为什么这么说?使用memcpy
复制数据块有许多正当理由。告诉你的人都不知道他们在说什么;我试图修复它,但注释与memcpy()调用不匹配。我会让你按照你想要的方式来修复它。另外,不要在C中强制转换malloc
的返回值。你不需要强制转换,因为任何指针类型都可以隐式(安全地)转换为void*
,并且它实际上可以隐藏错误。嗯,事实上,我被告知永远不要直接在内存中创建指针,因为这样可能会覆盖一些重要的内容。但这在内核编码(这是一种玩具练习的一部分)中是有意义的。@user1777900:或图像处理,或硬件接口。。。等等。我们在这里讨论的是C,你打算如何准确地远离指针?“因为我知道你真的不应该在现实生活中这样做”-嗯。。。你为什么这么说?使用memcpy
复制数据块有许多正当理由。告诉你的人都不知道他们在说什么;我试图修复它,但注释与memcpy()调用不匹配。我会让你按照你想要的方式来修复它。另外,不要在C中强制转换malloc
的返回值。你不需要强制转换,因为任何指针类型都可以隐式(安全地)转换为void*
,并且它实际上可以隐藏错误。嗯,事实上,我被告知永远不要直接在内存中创建指针,因为这样可能会覆盖一些重要的内容。但这在内核编码(这是一种玩具练习的一部分)中是有意义的。@user1777900:或图像处理,或硬件接口。。。等等。我们在这里讨论的是C,您打算如何准确地远离指针?除了取消对void
指针的引用(这是不允许的),这个例子有什么幼稚之处?我认为它满足了兼容的memcpy()
实现的所有要求。我几乎错过了void ptr@CarlNorum的取消引用。顺便说一句,是的,你是对的,这一点都不幼稚。它很可能是在指令中编写的,这些指令利用了更大的块拷贝,假设它可用(在现代CPU上),除了取消对void
指针的引用(这是不允许的),这个例子有什么幼稚之处?我认为它满足了兼容的memcpy()
实现的所有要求。我几乎错过了void ptr@CarlNorum的取消引用。顺便说一句,是的,你是对的,这一点都不幼稚。它可能是在指令中编写的,假设它是可用的(它将在现代CPU上)它将利用更大的块拷贝