Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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
new在任何情况下都会返回NULL吗? P>我知道,在新分配内存失败的情况下,根据C++标准,它应该抛出STD::BADYOLL异常。但我听说有些编译器,如VC6(或CRT实现?)不遵守它。这是真的吗?我这样问是因为在每个新语句之后检查NULL会使代码看起来非常难看 >基于C++规范,当使用没有PARAMS的纯新的时,它总是抛出STD::BADYOLL,但是当然也会有一些不兼容的编译器。p> 我不会代码,而是遵从非C++兼容编译器。VC6就是其中之一_C++_Visual C++_Memory Management_New Operator_Visual C++ 6 - Fatal编程技术网

new在任何情况下都会返回NULL吗? P>我知道,在新分配内存失败的情况下,根据C++标准,它应该抛出STD::BADYOLL异常。但我听说有些编译器,如VC6(或CRT实现?)不遵守它。这是真的吗?我这样问是因为在每个新语句之后检查NULL会使代码看起来非常难看 >基于C++规范,当使用没有PARAMS的纯新的时,它总是抛出STD::BADYOLL,但是当然也会有一些不兼容的编译器。p> 我不会代码,而是遵从非C++兼容编译器。VC6就是其中之一

new在任何情况下都会返回NULL吗? P>我知道,在新分配内存失败的情况下,根据C++标准,它应该抛出STD::BADYOLL异常。但我听说有些编译器,如VC6(或CRT实现?)不遵守它。这是真的吗?我这样问是因为在每个新语句之后检查NULL会使代码看起来非常难看 >基于C++规范,当使用没有PARAMS的纯新的时,它总是抛出STD::BADYOLL,但是当然也会有一些不兼容的编译器。p> 我不会代码,而是遵从非C++兼容编译器。VC6就是其中之一,c++,visual-c++,memory-management,new-operator,visual-c++-6,C++,Visual C++,Memory Management,New Operator,Visual C++ 6,不过,删除指针后,最好将指针设置为NULL。因此,仍然需要检查NULL 话虽如此,以下是清理代码的几个选项: char *p = new(std::nothrow) char[1024]; 选项1:设置您自己的新处理程序 清理代码的安全方法是调用:first 然后,您可以在处理程序中检查NULL,并在返回NULL时抛出std::bad_alloc 如果你更喜欢例外情况,那么这是你最好的选择。如果您希望更好地返回NULL,那么也可以通过在新处理程序中执行catch来实现 选项2:使用重载的新

不过,删除指针后,最好将指针设置为NULL。因此,仍然需要检查NULL

话虽如此,以下是清理代码的几个选项:

 char *p = new(std::nothrow) char[1024];
选项1:设置您自己的新处理程序

清理代码的安全方法是调用:first

然后,您可以在处理程序中检查NULL,并在返回NULL时抛出std::bad_alloc

如果你更喜欢例外情况,那么这是你最好的选择。如果您希望更好地返回NULL,那么也可以通过在新处理程序中执行catch来实现

选项2:使用重载的新

C++标准头文件定义了一个空的结构NoLoad。您可以在new中使用此结构的对象来获取其总是返回NULL的重载版本

void* operator new (size_t size, const std::nothrow_t &);
void* operator new[] (void *v, const std::nothrow_t &nt);
因此,在您的代码中:

 char *p = new(std::nothrow) char[1024];

这里是

VC6在这方面默认不符合要求。VC6的
new
返回
0
(或
NULL

以下是Microsoft关于此问题的知识库文章,以及他们建议的使用自定义
新的
处理程序的解决方法:

如果您有为VC6行为编写的旧代码,您可以通过在名为
nothrownew.obj
的对象文件中链接,在较新的MSVC编译器(如7.0及更高版本)中获得相同的行为。实际上,在7.0和7.1编译器(VS2002和VS2003)中有一个参数来确定它们是默认为非抛出还是抛出
new

似乎在8.0(VS2005)中——现在它总是默认为抛出new,除非您专门链接到
nothrownew.obj

请注意,您可以使用
std::nothrow
参数指定希望
new
返回
0
,而不是抛出
std::bad_alloc

SomeType *p = new(std::nothrow) SomeType;
这在VC6中似乎是可行的,因此这可能是一种或多或少机械地修复代码的方法,使其与所有编译器的工作方式相同,这样您就不必重新处理现有的错误处理。

我想补充一点(有点争议)意见,即在尝试分配后检查NULL几乎是徒劳的。如果你的程序遇到这种情况,很有可能你只能快速退出。很可能任何后续分配尝试也会失败

在不检查NULL的情况下,后续代码将尝试取消对NULL指针的引用,该指针倾向于快速退出程序,退出条件相对唯一(且易于调试)

我不是想说服你不要检查NULL,这当然是认真的编程。但你不会从中获得太多,除非在非常特殊的情况下,你可能可以存储一些恢复信息(而不分配更多内存),或者释放不太重要的内存,等等。但这些情况对大多数人来说相对较少


有鉴于此,我相信编译器会亲自抛出错误的alloc,至少在大多数情况下是这样。

我理解删除后NULL的设置。但我的问题是这样的代码:int*p=newint;如果(p==NULL){//log about memory allocation failure..return;}您可以在新的处理程序中抛出bad_alloc,但甚至没有什么可以检查NULL。您也不能通过处理程序修改new的返回值。在delete之后将指针设置为NULL可能是一个好主意(对于C)。但是在C++中,代码气味表明RAII没有被正确使用。我认为这个建议过时了。马丁:不,只是…不。试着在调试器中找出程序的状态,空指针是你的朋友。我不是说这是一件坏事。只是这是一种代码气味。如果您有一个可能在删除后使用的指针,则需要担心更大的设计问题。将原始指针设置为NULL是一个警告标志;询问为什么这个指针仍然可以被滥用!错误的版本号。它在5.0中被破坏(正如你链接到的文章所说)。它在6.0中得到了修复。VC6在默认情况下也返回空值-我刚刚测试了它。根据“kftDy56f”链接,VC7和VC7.1(VS2002和VS2003)中的行为也可以返回null,这取决于是否链接了LBC*.LIB或LICPCP*C++(CRT或C++标准库)。我对测试没有兴趣。公平地说,VC6在C++标准被批准之前发布,这也是它不符合的原因之一。诚然,当时该标准已接近完成,但我们必须记住,存在开发周期,VC6可能至少在一年前启动。“代码完成”建议预先分配内存“安全网”,以便在内存不足的情况下使用,例如,使在退出前保存调试信息成为可能。问题是,在现代虚拟机系统上,如果您的(虚拟)内存快要用完,那么它将分页太多,完全无法使用。在某些情况下,您的操作系统将允许您分配内存,而不在内存中真正映射新页面(惰性评估)。但当你尝试使用那个内存时,没有可用的内存,进程会被终止。便宜的硬盘和大交换文件的问题会少一些……我不同意你的看法;有时无法