【问题标题】:C Valgrind - Source and destination overlap in memcpyC Valgrind - memcpy中的源和目标重叠
【发布时间】:2012-12-05 10:32:27
【问题描述】:

我是 c 编程新手,我正在编写一个简单的客户端服务器应用程序。我收到这条消息:

 Source and destination overlap in memcpy(0x41f0beb, 0x41f0258, 69141077)
    ==9522==    at 0x402D9A9: memcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==9522==    by 0x8049C13: message_to_buffer (message.c:92)

具体代码如下:

case CT_ENTRY://100
{
    int c=(2+2+4+strlen(msg->content.entry->key)-1+4+4+strlen(msg->content.entry->value->data));
    char *offset=malloc(c);
    *msg_buf=offset;
    memcpy(offset,&opcode,2);
    offset+=2;
    memcpy(offset,&ctype,2 );
    offset+=2;
    int ks=strlen(msg->content.entry->key);
    int ksc=host_to_net(ks);
    memcpy(offset,&ksc,4);
    offset+=4;
    memcpy(offset, msg->content.entry->key, ks);
    offset+=ks;
    int l=host_to_net(get_time());
    memcpy(offset,&l,4);
    offset+=4;
    int ds=host_to_net(msg->content.entry->value->datasize);
    memcpy(offset,&ds,4);
    offset+=4;

    // this line here!
    memcpy(offset,msg->content.entry->value->data, msg->content.value->datasize);

    return c;
    break;

违规行是

memcpy(offset,msg->content.entry->value->data, msg->content.value->datasize);

谁能解释一下为什么会这样?谢谢

【问题讨论】:

  • 您确定69141077datasize 值正确吗?
  • 您正在复制将近 70 兆字节的数据,这真的正确吗?
  • 是的,这似乎是问题所在。它应该只有几个字节。感谢您为我指明正确的方向。

标签: c valgrind memcpy


【解决方案1】:

如果源和目标内存块重叠,您必须使用memmove 而不是memcpy

【讨论】:

  • 但是为什么它们会重叠呢?它们是完全不同的变量。
  • @UserConscious 即使变量不同,指向的区域也可能不同。
  • 既然我想把data的内容复制到offset,那怎么解决呢?
  • @UserConscious:从 valgrind 的输出来看,它的大小似乎非常大~69MB。
  • 在使用 memmove 而不是 memcpy 之前,您应该三重检查您的代码。通常问题是缓冲区溢出,您不想重叠内存块。
【解决方案2】:

您告诉memcpy() 复制 69141077 字节的数据。这看起来比您在offset 中实际分配的大小要大得多(除非这些字符串真的巨大)。

所以,这是缓冲区溢出。检查msg->content.value->datasize 的内容是否与分配offset 时计算的大小匹配。

【讨论】:

  • 是的,这似乎是问题所在。
【解决方案3】:

memcpy() 的手册页说:

memcpy() 函数将 n 个字节从内存区域 s2 复制到内存中 区域 s1。如果 s1 和 s2 重叠,则行为未定义。应用在 哪些 s1 和 s2 可能重叠应该使用 memmove(3) 代替。

【讨论】:

  • OP 已经声明他的区域不应该重叠,所以使用memmove() 的建议并不能真正解决问题。
猜你喜欢
  • 2011-09-13
  • 2016-05-16
  • 1970-01-01
  • 1970-01-01
  • 2017-09-10
  • 2014-10-27
  • 2014-03-23
  • 1970-01-01
  • 2017-08-22
相关资源
最近更新 更多