for 循环与赋值运算符

For-loop vs assignment operator

本文关键字:赋值运算符 循环 for      更新时间:2023-10-16

直接赋值(=)是否与将某些内容转换为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;

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

编辑:根据答案,内存复制是否与"="相同

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

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

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

首先,这不是C++。这是丑陋的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 有三个参数,一个目的地、一个源和以字节为单位的大小。确保两者匹配,您将获得一个快速的每字节副本。

使用 = 运算符的直接赋值绝对不一样作为复制字节的for循环。 =运算符尊重类型,它的作用将取决于类型。 逐字节复制是在大多数情况下未定义的行为。 在你的特殊情况下,我会期望编译器生成等效于处理数据作为一个无符号的长长,并复制它,只需要一两个机器说明。 但那只是因为您定义的类型。 通常,为编译器提供尽可能多的信息尽你所能,并信任它;它通常会做得更好。

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

将格式化数据写入可传输格式是序列化,C++,有几种方法可以做到这一点。 有几件事需要考虑:格式应该是ASCII,XML,二进制,如果是二进制,应该是跨平台的(endianess,alignation)。 无论如何,将结构复制到字节缓冲区的幼稚方式几乎是不可取的。

您可以考虑以下选项:

  • 当它可能采用ASCII格式时,最直接的方法是使用iostreams。
  • boost.serialization
  • 外部库(公平:Boost也是其中之一):Poco,谷歌缓冲区协议,...
  • 滚动你自己的(基于转换基元)

另请参阅此问题