0

直接赋值( =)与将某些内容投射到char*然后使用for循环逐字节复制它是否相同?*
我想知道一种方法是否比另一种方法有优势。

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

4 回答 4

10

这基本上就是memcpy这样做的,并且对POD 类型有效(假设sizeof(Test)确实是 8)。但是,memcpy几乎可以肯定会更快,因为编译器将具有特殊优化的汇编程序例程。

如果您使用非 POD 类型尝试此(或),您将调用未定义的行为。memcpy所以一般来说,你应该使用std::copy或只使用赋值。

您还应该避免malloc使用 C++,因为它不是类型安全的;如果需要,请使用new, 或放置。new

于 2012-06-27T14:33:35.617 回答
1

首先,这不是 C++。这是丑陋的 C。您正在手动分配一块大小为 1024 字节的内存,并在裸指针中捕获其地址。此外,在代码示例中,您永远不会释放任何它,从而泄漏了 MB 内存。当涉及到 C++ 时,这被认为是一种非常糟糕的做法。

C++ 不是带有类的 C,它是一种美丽的语言,它只能通过与标准库结合使用并坚持更好的设计模式来表达自己在更好的内存管理中。甚至new在不必要的时候都回避,更不用说malloc

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

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

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

我什至不打算对此发表评论。天啊……不仅不好,而且没用。您正试图将一个struct A躺在堆栈上的实例(一个常规的“对象”/var)强制转换为char*. 你错过了&Test.

如果您选择这条路,请使用 memcpy,但请考虑改进您的 C++ 方法。memcpy 接受三个参数,一个目标,一个源和字节大小。确保两者匹配,您将获得快速的每字节副本。

于 2012-06-27T15:02:19.283 回答
0

使用运算符的直接赋值=绝对不同于for复制字节的循环。操作员尊重类型,它的=作用取决于类型。在大多数情况下,逐字节复制是未定义的行为。在您的特定情况下,我希望编译器生成的东西相当于将数据视为 unsigned long long,并仅使用一两条机器指令进行复制。但这仅仅是因为您定义的类型的特殊性。一般来说,给编译器尽可能多的信息,并相信它;它通常会做得更好。

于 2012-06-27T15:08:49.143 回答
0

这不是对 OP 问题的直接回答,而是对我认为他正在努力实现的目标的回答。

将格式化数据写入可传输格式是序列化,在 C++ 中,有几种方法可以做到这一点。有几件事情需要考虑:格式是否应该是 ascii、xml、二进制,如果是二进制,是否应该是跨平台的(字节序、对齐)。在任何情况下,将结构复制到字节缓冲区的幼稚方式几乎是不可取的。

您可以考虑以下选项:

  • 当它可能是 ascii 格式时,最直接的方法是使用 iostreams
  • boost.序列化
  • 外部库(很公平:boost 也是其中之一):poco、google 缓冲协议、...
  • 滚动你自己的(基于转换原语)

另见这个问题

于 2012-06-27T15:30:35.443 回答