【问题标题】:C - copying directly from memory using memcpyC - 使用 memcpy 直接从内存中复制
【发布时间】:2013-01-25 23:28:25
【问题描述】:

这纯粹是一个家庭作业问题,因为我知道你真的不应该在现实生活中尝试这样做。但我一直在努力解决这个问题。假设我们知道我们想要复制的永久起始位置以及我们想要复制的内存块的确切大小。假设我们的源是从 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 有时如何分配内存感到困惑......

编辑:: 糟糕,变量混乱。现已修复。

【问题讨论】:

  • “既然我知道你真的不应该在现实生活中尝试这样做” - 嗯……你为什么这么说?使用memcpy 复制数据块有很多正当理由。告诉你的人不知道他们在说什么。
  • 您的示例代码中的变量有一些有趣的事情;我试图修复它,但 cmets 与 memcpy() 调用不匹配。我会让你按照你的意思修复它。
  • 另外,不要在 C 中强制转换 malloc 的返回值。你不需要强制转换,因为任何指针类型都可以隐式(并且安全地)转换为 void*,并且它实际上可以隐藏错误。
  • 好吧,不是这个,而是我被告知永远不要将指针直接指向内存,因为你最终可能会覆盖一些重要的东西。但这在内核编码中是有意义的(这是一种玩具练习的一部分)。
  • @user1777900:或者图像处理,或者硬件接口......等等。我们这里说的是C,你建议如何完全远离指针?

标签: c memory memcpy


【解决方案1】:

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++; }
}

所以是的,它从sourcedest 开始向上计数

【讨论】:

  • 除了取消引用void 指针(这是不允许的),这个例子有什么天真之处?我认为它满足合规memcpy() 实现的所有要求。
  • 我几乎会错过对 void ptr @CarlNorum 的取消引用。顺便说一句,是的,你是对的,一点都不幼稚..
  • 假设它可用(它将在现代 CPU 上),它可能会被写入利用更大块副本的指令中
【解决方案2】:

是的,memcpy() 从您传递给它的基地址开始计数。

如果您最终要为嵌入式系统编写“裸机”类型的无操作系统软件,或者您自己实现操作系统或内核,您可能非常需要这样做。

【讨论】:

    猜你喜欢
    • 2017-11-13
    • 2021-12-27
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    相关资源
    最近更新 更多