Malloc vs新
我正在为使用MPI进行高性能计算(10 ^ 5 - 10 ^ 6内核)的项目审查其他人的C ++代码。 该代码旨在允许不同体系结构中(可能)不同机器之间的通信。 他写了一篇评论,内容如下:
我们通常会使用new
和delete
,但在这里我使用malloc
和free
。 这是必要的,因为有些编译器会在使用new
数据时填充不同的数据,导致在不同平台之间传输数据时出错。 malloc
不会发生这种情况。
这不符合我从标准new
vs malloc
问题中所知道的任何东西。
new / delete和malloc / free有什么区别? 暗示编译器可以以不同的方式计算对象的大小(但为什么与使用sizeof
不同呢?)。
malloc&placement new与new是一个相当流行的问题,但只讨论malloc
不使用的new
构造malloc
,这与此无关。
malloc如何理解对齐? 说内存保证与我以前想过的new
或malloc
正确对齐。
我的猜测是,他在过去的某段时间误诊了自己的bug并推断出new
和malloc
给出了不同数量的填充,我认为这可能不是真的。 但我无法在Google或任何以前的问题中找到答案。
帮助我,StackOverflow,你是我唯一的希望!
IIRC有一个挑剔点。 malloc
保证返回任何标准类型对齐的地址。 ::operator new(n)
只保证返回一个对应于任何不大于n的标准类型的地址,并且如果T
不是一个字符类型,那么只需要new T[n]
返回一个与T
对齐的地址。
但是,这只有在玩特定于实现的技巧时才有意义,比如使用指针的底部几位来存储标志,或者依靠地址来获得比其严格需要更多的对齐方式。
它不会影响对象内的填充,不管分配占用的内存的方式如何,它都必须具有完全相同的布局。 所以很难看出差异如何导致数据传输错误。
有没有什么迹象表明该评论的作者认为堆栈或全局变量中的对象,无论他认为它们是“像malloc一样填充”还是“像新填充一样”? 这可能会提供这个想法来自何处的线索。
也许他感到困惑,但也许他所谈论的代码不仅仅是malloc(sizeof(Foo) * n)
与new Foo[n]
之间的直接差异。 也许它更像是:
malloc((sizeof(int) + sizeof(char)) * n);
与
struct Foo { int a; char b; }
new Foo[n];
也就是说,他可能会说“我使用malloc”,但意思是“我手动将数据打包到未对齐的位置而不是使用结构”。 实际上malloc
不需要手动打包结构,但没有意识到这是一个较小程度的混淆。 有必要定义通过线路发送的数据布局。 当使用结构时,不同的实现会以不同的方式填充数据。
你的同事可能已经有了new[]/delete[]
的魔法cookie(这是删除数组时实施的信息)。 但是,如果使用由new[]
返回的地址开始的分配(与分配器相反),这不会成为问题。
包装似乎更有可能。 ABI中的变化可能(例如)导致结尾处添加不同数量的尾随字节(这受到对齐的影响,也考虑到数组)。 使用malloc,可以指定结构的位置,从而更容易将其移植到外国ABI中。 这些变化通常通过指定传输结构的对齐和包装来防止。
对象的布局不能取决于它是使用malloc
还是new
分配的。 它们都返回相同类型的指针,并且当您将此指针传递给其他函数时,它们将不知道该对象是如何分配的。 sizeof *ptr
只是依赖于ptr
的声明,而不是如何分配。
上一篇: Malloc vs new