就各自的语言标准而言,C只通过malloc()家族提供动态内存分配,而在C++中,最常见的分配形式是::operator new().C风格的malloc在C++中也可用,许多"Baby‘s First Allocator"示例使用它作为其核心分配函数,但我很好奇当代编译器如何实现实际的生成操作符-new.

它是一个大约malloc()的瘦包装器,还是因为典型的C++程序与典型的C程序相比,内存分配行为有很大不同?

[Edit:我认为主要区别通常被描述为:C程序有较少、较大、较长的分配,而C++程序有很多、较小、较短的分配.如果这是错误的,请随意插话,但听起来似乎有人会从考虑到这一点中受益.]

对于像GCC这样的编译器来说,只有一个内核分配实现并将其用于所有相关语言是很容易的,所以我想知道在试图优化每种语言的最终分配性能的细节方面是否存在差异.


谢谢你所有精彩的回答!看起来GCC用一零二完全解决了这个问题,微软的核心也是用一百.有人知道msvc-malloc是如何实现的吗?

推荐答案

以下是g++ 4.6.1使用的实现:

_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz) throw (std::bad_alloc)
{
  void *p;

  /* malloc (0) is unpredictable; avoid it.  */
  if (sz == 0)
    sz = 1;
  p = (void *) malloc (sz);
  while (p == 0)
    {
      new_handler handler = __new_handler;
      if (! handler)
#ifdef __EXCEPTIONS
        throw bad_alloc();
#else
        std::abort();
#endif
      handler ();
      p = (void *) malloc (sz);
    }

  return p;
}

这可以在g++源代码发行版的libstdc++-v3/libsupc++/new_op.cc中找到.

正如你所见,这是一个相当薄的包装约malloc.

edit在许多系统上,通常通过调用mallopt或设置环境变量,可以微调malloc的行为.下面是一篇article篇讨论Linux上可用的一些功能的文章.

According to Wikipedia,glibc版本2.3+使用称为ptmalloc的分配器的修改版本,该分配器本身是由Doug Lea设计的dlmalloc的派生.有趣的是,在"article about dlmalloc"中,Doug Lea给出了以下观点(强调我的观点):

在编写了C++之后,我编写了第一个版本的分配器

然而,我很快意识到, for each 用户构建一个特殊的分配器 倾向于动态分配和大量使用的新类是 在构建各种通用编程时不是一个好策略 我当时正在编写的支持类.(从1986年到1991年,我是 (libg++的主要作者,GNU C++库.)一个更广泛的 需要一个解决方案--编写an allocator that was good enough under normal C++ and C loads个,这样程序员就不会受到诱惑 编写特殊用途的分配器,除非在非常特殊的情况下 条件.

这篇文章描述了一些主要的设计目标, 算法,以及此分配器的实现注意事项.

C++相关问答推荐

插入元素后,Sizeof操作符无法正常工作

在x86汇编中,为什么当分子来自RDRAND时DIV会引发异常?

漏洞仅出现在FreeBSD上,但在Windows、Linux和MacOS上运行得非常好

为什么这个select()会阻止?

字符数组,字符指针,在一种情况下工作,但在另一种情况下不工作?

为什么双重打印与C中的float具有不同的大小时具有相同的值?

C是否用0填充多维数组的其余部分?

C-使用指针返回修改后的整数数组

我怎么才能用GCC编译一个c库,让它包含另一个库呢?

为什么中断函数会以这种方式影响数组?

为什么我可以在GCC的标签后声明变量,但不能声明Clang?

#定义SSL_CONNECTION_NO_CONST

S和查尔有什么不同[1]?

接受任何参数的函数指针是否与接受不同参数的函数兼容

使用C++中的字符串初始化 struct 时,从‘char*’初始化‘char’使指针变为整数,而不进行强制转换

将某些内容添加到链接列表时,列表中的其他项将使用最后添加的项的名称

Dlsym()的手册页解决方法仍然容易出错?

C: NULL>;NULL总是false?

在 C 中的 scanf() 格式说明符中使用宏获取字符串长度

运行以下 C 程序时出现分段错误