C++ malloc和new的实现差异。堆栈实现?
在分配内存时,如果内存不可用,新操作符将引发异常。另一方面,malloc返回NULL。在执行方面存在差异的原因是什么。另外,在静态内存分配上,即在堆栈上,如果内存不足,是否存在异常 我已经通过了链接C++ malloc和new的实现差异。堆栈实现?,c++,algorithm,memory-management,C++,Algorithm,Memory Management,在分配内存时,如果内存不可用,新操作符将引发异常。另一方面,malloc返回NULL。在执行方面存在差异的原因是什么。另外,在静态内存分配上,即在堆栈上,如果内存不足,是否存在异常 我已经通过了链接 但是我没有得到关于这两种方法在实施上的区别的答案。我想,一个重要的区别在于: malloc是分配内存的C方式;在C语言中也没有例外 新< /代码>是C++、面向对象和所有的方式;C++中也有例外,使用它们更干净。 为什么在C++中保持 Malc C/代码>?我想这是因为C++编译器也可以用C
但是我没有得到关于这两种方法在实施上的区别的答案。我想,一个重要的区别在于:
是分配内存的C方式;在C语言中也没有例外malloc
为什么在C++中保持<代码> Malc C/代码>?我想这是因为C++编译器也可以用C代码……/P>工作。
。。。但是我经常听到(从老师,我几年前还在学校),在C++中使用<代码> MalOC/<代码>,而应该使用<代码> < < /代码>。 < P> <代码> Malc 不能抛出异常,因为这将打破与C.<代码>的兼容性>新< /COD>抛出异常,因为这是C++中错误的首选方式。
据我所知,在早期版本的C++中,<代码>新< /COD>确实在故障时返回0,
< P> C代码的问题是,您应该检查函数的返回值以确保它们正确工作。但是编写了很多没有检查返回值的代码,结果在您最不希望返回值的时候非常好地爆发了 在最坏的情况下,它甚至不会立即崩溃,但会继续破坏内存,并在错误流下游数英里处崩溃 因此,C++中的异常诞生了。 现在,当出现错误时,代码不会继续(因此没有内存损坏),而是展开堆栈(可能会迫使应用程序退出)。如果可以处理该问题,则必须在继续之前显式添加代码来处理该情况。这样您就不会意外忘记不检查错误条件;您要么检查它,要么应用程序将退出 新产品的使用适合这种设计。如果无法分配内存,则必须显式处理错误。
没有机会忘记检查空指针。因此,您不能因为意外使用空指针而破坏内存 另外,在静态内存分配上,即在堆栈上,如果内存不足,是否存在异常 不幸的是,您不能依赖于此。
堆栈溢出的情况由实现定义。在许多系统上,甚至不可能检测到导致内存损坏和可能最终崩溃的情况 注
如果您#include,则可以使用new的无抛出版本,该版本在没有内存时返回NULL。除非有特殊需要,否则最好避免使用此方法。为了完整起见,还请记住,您可以使用
nothrow
模拟旧的(非抛出)方法——这尤其适用于代码中性能关键的部分:
// never throws
char* ptr = new (nothrow) char [1024*1024];
// check pointer for succeeded allocation
if ( !ptr ) {
... // handle error
}
冒着可能增加一些混乱的风险
是一个常规的C函数。因为它是C,所以它只能通过适合C程序的方式发出错误信号:使用返回值、指针传递的参数或全局变量(如malloc
)errno
<>代码> new < /Cuff>引入C++表达式,调用<代码>运算符new <代码>获取内存,然后<强>构造< /强>对象。
操作符new
或构造函数可以抛出
注意:new
表达式有一个无抛出版本
大多数操作符new
通常是根据malloc
实现的,但正如我所指出的,新的
表达式不仅仅是获取内存,因为它还构建对象
它还负责管理直到将其发布给您。也就是说,如果构造函数抛出,那么它会正确地处理分配的内存,并且在new[]
表达式(构建数组)的情况下,调用已经构建的对象的析构函数
关于堆栈溢出:这取决于编译器和操作系统。操作系统可能会指出问题并发出错误信号,编译器可能会进行检查等等
注意,gcc在编译时引入了splitstack选项,它包括分配一个最小的堆栈,然后根据需要增加它。这巧妙地避开了可能的堆栈溢出问题,但引入了另一个二进制兼容性问题,因为与未使用此选项构建的代码的交互可能会变得模糊;我不知道他们计划如何具体实现这一点。在性能关键型代码中,也许您不应该分配大量堆内存。:-。至少在C++0x中,需要默认版本的new(nothrow)来调用正常的new、捕获异常并返回NULL。[18.6.1.1]实际上存在
new
的无抛出重载,它返回0而不是抛出。