For循环vs赋值运算符

时间:2012-06-27 14:31:16

标签: c++ copy bit-manipulation

直接赋值( ie =)是否与向char*转换内容然后使用for循环逐字节地复制它一样?< SUP> *
我想知道一种方法是否优于另一种方法。

struct A
{
    int a;
    int b;
} Test;

void* Buffer = malloc(1024);


// Casting and byte copying
for (int i=0; i != 8; i++)
{
    ((char*)Buffer)[i] = ((char*)Test)[i];
}

// Assignment
((A*)Buffer)[0] = Test;

*所有类型都是按位可复制的。

编辑: 根据答案,memcopy与'='

相同

4 个答案:

答案 0 :(得分:10)

这基本上是memcpy的作用,对POD types有效(假设sizeof(Test)确实为8)。但是,memcpy几乎肯定会更快,因为编译器将具有特殊优化的汇编程序例程。

如果您尝试使用非POD类型(或memcpy),则会调用未定义的行为。因此,一般情况下,您应该使用std::copy或仅使用作业。

你也应该避免在C ++中使用malloc,因为它不是类型安全的;如果必须,请使用newplacement new

答案 1 :(得分:1)

首先,这不是C ++。这很难看。你手动分配一个1024字节大小的内存块,用裸指针捕获它的地址。此外,在代码示例中,您永远不会释放任何内容,泄漏MB内存。对于C ++来说,这被认为是一种非常糟糕的做法。

C ++不是带有类的C,它是一种漂亮的语言,它只能通过将它与标准库结合使用来表达自己,并坚持使用OO编程自然而然的更好的设计模式,特别是RAII的概念,一般封装这可以带来更好的内存管理。即使new在不必要时也会被规避,更不用说malloc了。

for (int i=0; i != 8; i++)

此外,您在这里做出了危险的假设,这可能导致未定义的行为。

((char*)Buffer)[i] = ((char*)Test)[i];

我甚至不打算对此发表评论。圣洁......不仅不好,而且不起作用。您试图将struct A的实例强制放在堆栈中,将常规“对象”/ var强制转换为char*。你错过了&Test

如果您采用此路径,请使用memcpy ,但请考虑改进您的C ++方法。 memcpy接受三个参数,一个目标,一个源和大小(以字节为单位)。确保两者匹配,您将获得快速的每字节副本。

答案 2 :(得分:0)

使用=运算符进行直接赋值肯定相同 作为复制字节的for循环。 =运算符尊重类型, 它的作用取决于类型。并逐字节复制 大多数情况下未定义的行为。在你的特殊情况下,我愿意 期望编译器生成等同于处理的东西 数据作为unsigned long long,只需要一两个就可以复制 机器说明。但这只是因为它的特殊性 您定义的类型。通常,为编译器提供尽可能多的信息 尽你所能,并相信它;它通常可以做得更好。

答案 3 :(得分:0)

这不是对OP问题的直接回答,而是对我认为他想要实现的目标的回答。

将格式化数据写入可转换格式为serialization,在C ++中,有几种方法可以执行此操作。有几件事需要考虑:格式应该是ascii,xml,二进制,如果是二进制,它应该是跨平台(endianess,alignment)。在任何情况下,将结构复制到字节缓冲区的简单方法几乎都不可取。

您可以考虑以下选项:

  • 当它可能是ascii格式时,最直接的方法是使用iostreams
  • boost.serialization
  • 外部库(足够公平:提升也是一个):poco,谷歌缓冲协议,......
  • 滚动自己(基于转换原语)

另见this question