Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ malloc和new的实现差异。堆栈实现?_C++_Algorithm_Memory Management - Fatal编程技术网

C++ malloc和new的实现差异。堆栈实现?

C++ malloc和new的实现差异。堆栈实现?,c++,algorithm,memory-management,C++,Algorithm,Memory Management,在分配内存时,如果内存不可用,新操作符将引发异常。另一方面,malloc返回NULL。在执行方面存在差异的原因是什么。另外,在静态内存分配上,即在堆栈上,如果内存不足,是否存在异常 我已经通过了链接 但是我没有得到关于这两种方法在实施上的区别的答案。我想,一个重要的区别在于: malloc是分配内存的C方式;在C语言中也没有例外 新< /代码>是C++、面向对象和所有的方式;C++中也有例外,使用它们更干净。 为什么在C++中保持 Malc C/代码>?我想这是因为C++编译器也可以用C

在分配内存时,如果内存不可用,新操作符将引发异常。另一方面,malloc返回NULL。在执行方面存在差异的原因是什么。另外,在静态内存分配上,即在堆栈上,如果内存不足,是否存在异常

我已经通过了链接
但是我没有得到关于这两种方法在实施上的区别的答案。我想,一个重要的区别在于:

  • malloc
    是分配内存的C方式;在C语言中也没有例外
  • <代码>新< /代码>是C++、面向对象和所有的方式;C++中也有例外,使用它们更干净。

为什么在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
}

冒着可能增加一些混乱的风险

  • malloc
    是一个常规的C函数。因为它是C,所以它只能通过适合C程序的方式发出错误信号:使用返回值、指针传递的参数或全局变量(如
    errno
  • <>代码> new < /Cuff>引入C++表达式,调用<代码>运算符new <代码>获取内存,然后<强>构造< /强>对象。
    操作符new
    或构造函数可以抛出
注意:
new
表达式有一个无抛出版本

大多数
操作符new
通常是根据
malloc
实现的,但正如我所指出的,
新的
表达式不仅仅是获取内存,因为它还构建对象

它还负责管理直到将其发布给您。也就是说,如果构造函数抛出,那么它会正确地处理分配的内存,并且在
new[]
表达式(构建数组)的情况下,调用已经构建的对象的析构函数

关于堆栈溢出:这取决于编译器和操作系统。操作系统可能会指出问题并发出错误信号,编译器可能会进行检查等等


注意,gcc在编译时引入了splitstack选项,它包括分配一个最小的堆栈,然后根据需要增加它。这巧妙地避开了可能的堆栈溢出问题,但引入了另一个二进制兼容性问题,因为与未使用此选项构建的代码的交互可能会变得模糊;我不知道他们计划如何具体实现这一点。

在性能关键型代码中,也许您不应该分配大量堆内存。:-。至少在C++0x中,需要默认版本的new(nothrow)来调用正常的new、捕获异常并返回NULL。[18.6.1.1]实际上存在
new
的无抛出重载,它返回0而不是抛出。