首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何实施新的(std::nothrow)?

如何实施新的(std::nothrow)?
EN

Stack Overflow用户
提问于 2013-03-08 10:34:57
回答 1查看 3.4K关注 0票数 9

我有一个C++程序,其中new操作符重载。问题是,如果我在new操作符中的分配失败,我仍然在调用构造函数。我知道我可以通过抛出std::bad_alloc来避免这种情况,但我不想这样做。

如何在重载的new操作符中失败,仍然不调用构造函数?本质上,我想实现类似于new (std::nothrow)的东西。

这里有一个例子来说明我的意思。注意,我正在测试的系统没有内存保护。所以访问并没有做什么

示例1:重载的新运算符

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <memory>

class Test {

public:

    Test(void) {
        printf("Test constructor\n");
    }

    void print(void) {
        printf("this: %p\n", this);
    }

    void* operator new(size_t size, unsigned int extra) {

        void* ptr = malloc(size + extra);
        ptr = NULL; // For testing purposes
        if (ptr == NULL) {
            // ?
        }
        return ptr;
    }
};

int main(void) {

    Test* t = new (1) Test;            
    t->print();
    printf("t: %p\n", t);

    return 0;
}

这样做的结果是:

代码语言:javascript
运行
复制
$ ./a.out
Test constructor
this: 00000000
t: 00000000

显然,当new失败时,解析器正在被调用。

示例2:使用new的大型类声明(std::new)

代码语言:javascript
运行
复制
#include <stdio.h>
#include <stdlib.h>
#include <memory>

class Test {

    int x0[0x0fffffff];
    int x1[0x0fffffff];
    int x2[0x0fffffff];
    int x3[0x0fffffff];
    int x4[0x0fffffff];
    int x5[0x0fffffff];
    int x6[0x0fffffff];
    int x7[0x0fffffff];
    int x8[0x0fffffff];
    int x9[0x0fffffff];
    int xa[0x0fffffff];
    int xb[0x0fffffff];
    int xc[0x0fffffff];
    int xd[0x0fffffff];
    int xe[0x0fffffff];
    int xf[0x0fffffff];

public:

    Test(void) {
        printf("Test constructor\n");
    }

    void print(void) {
        printf("this: %p\n", this);
    }
};

int main(void) {

    Test* t = new (std::nothrow) Test;    
    t->print();
    printf("t: %p\n", t);

    return 0;
}

这样做的结果是:

代码语言:javascript
运行
复制
this: 00000000
t: 00000000    

显然,构造器是,而不是,在new失败时被调用。

那么,如何在重载的new (std::nothrow)操作符中实现new的功能呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-08 10:43:50

编译器在调用operator new之后,在调用析构函数之前是否检查空指针,取决于分配程序函数是否具有无抛出的异常规范。如果没有,编译器假设如果没有可用内存,operator new将抛出。否则,它假设operator new将返回一个空指针。就您的情况而言,您的operator new应该是:

代码语言:javascript
运行
复制
void* operator new( size_t size, unsigned int extra ) throw()
{
    //...
}

或者,如果您可以指望C++11支持:

代码语言:javascript
运行
复制
void* operator new( size_t size, unsigned int extra) noexcept
{
}
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15291971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档