Malloc vs new - 不同的填充

hca*_*ver 108 c++ malloc padding new-operator

我正在审查其他人使用MPI进行高性能计算(10 ^ 5 - 10 ^ 6核心)的项目的C++代码.该代码旨在允许不同体系结构上(可能)不同机器之间的通信.他写了一条评论,说的是:

我们通常使用newdelete,但在这里我正在使用mallocfree.这是必要的,因为一些编译器在new使用时将以不同方式填充数据,从而导致在不同平台之间传输数据时出错.这不会发生malloc.

这与我从标准newvs malloc问题中所知道的任何内容都不符合.

new/delete和malloc/free有什么区别?提示编译器可以不同地计算对象的大小(但那么为什么它与使用不同sizeof?).

malloc&placement new vs. new是一个相当受欢迎的问题,但只讨论new使用构造函数而malloc不是,这与此无关.

malloc如何理解对齐?他说保证记忆与任何一个new或者malloc我之前想过的一致.

我的猜测是,他在过去的某个时间误诊了自己的错误并推断出newmalloc提供不同数量的填充,我认为这可能不是真的.但我无法通过谷歌或以前的任何问题找到答案.

帮助我,StackOverflow,你是我唯一的希望!

Ste*_*sop 25

IIRC有一个挑剔点.malloc保证返回与任何标准类型对齐的地址.::operator new(n)只保证返回一个不大于n的任何标准类型对齐的地址,如果T不是字符类型new T[n],则只需要返回一个对齐的地址T.

但这只有在你正在玩特定于实现的技巧时才有用,例如使用指针的底部几位来存储标志,或者依赖地址来获得比它严格需要的更多对齐.

它不会影响对象内的填充,无论您如何分配它占用的内存,它都必须具有完全相同的布局.因此,很难看出差异如何导致传输数据的错误.

是否有任何迹象表明该评论的作者对堆栈中的对象或全局中的对象有何看法,无论他认为他们是"填充像malloc"还是"填充像新的"?这可能会提供这个想法来自何处的线索.

也许他很困惑,但也许他所谈论的代码不仅仅是malloc(sizeof(Foo) * n)vs 之间的直接差异new Foo[n].也许它更像是:

malloc((sizeof(int) + sizeof(char)) * n);
Run Code Online (Sandbox Code Playgroud)

struct Foo { int a; char b; }
new Foo[n];
Run Code Online (Sandbox Code Playgroud)

也就是说,也许他 "我使用malloc",但意思是 "我手动将数据打包到未对齐的位置而不是使用结构".实际上malloc不需要手动打包结构,但没有意识到这是一个较小程度的混乱.有必要定义通过线路发送的数据布局.使用结构时,不同的实现将以不同方式填充数据.

  • @Hbcdev:好的`char`数组根本就没有填充,所以我会坚持使用"confused"作为解释. (5认同)

jus*_*tin 5

你的同事可能已经new[]/delete[]记住了神奇的cookie(这是删除数组时实现所使用的信息).但是,如果使用从返回的地址开始的分配new[](而不是分配器),则这不会成为问题.

包装似乎更有可能.ABI的变化可以(例如)导致在结构的末尾添加不同数量的尾随字节(这受到对齐的影响,也考虑数组).使用malloc,可以指定结构的位置,从而更容易移植到外国ABI.通常通过指定转移结构的对齐和包装来防止这些变化.

  • 这是我最初的想法,"结构大于其各部分的总和"问题.也许这就是他的想法最初来自的地方. (2认同)