Как реализуется " new (std::nothrow)"?
у меня есть программа на C++, где new
оператор перегружен. Проблема в том, что
если мое распределение в new
оператор не работает, я все еще вызываю конструктор.
Я знаю, что могу избежать этого, бросая std::bad_alloc
, но я не хочу этого делать.
как я могу потерпеть неудачу в моем перегруженном new
оператор и все еще не вызываете Мой конструктор?
По сути, я хочу реализовать что-то вроде new (std::nothrow)
.
вот пример, чтобы проиллюстрировать, что я имею в виду. Примечание. что система, которую я тестирую
on не имеет защиты памяти. Так что доступ NULL
ничего не происходит
Пример 1 : перегруженный оператор new
#include <stdio.h>
#include <stdlib.h>
#include <memory>
class Test {
public:
Test(void) {
printf("Test constructorn");
}
void print(void) {
printf("this: %pn", 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: %pn", t);
return 0;
}
выход для этого:
$ ./a.out
Test constructor
this: 00000000
t: 00000000
ясно constrcutor вызывается, когда new
ошибка.
Пример 2: огромное объявление класса с новым (std::nothrow)
#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 constructorn");
}
void print(void) {
printf("this: %pn", this);
}
};
int main(void) {
Test* t = new (std::nothrow) Test;
t->print();
printf("t: %pn", t);
return 0;
}
выход для этого есть:
this: 00000000
t: 00000000
ясно constrcutor составляет не вызывается, когда new
ошибка.
Итак, как мне реализовать new (std::nothrow)
функциональность в моем
перегружен new
оператор?
1 ответов
проверяет ли компилятор нулевой указатель после вызова
operator new
или нет, перед вызовом деструктора, зависит от
имеет ли функция распределителя исключение non-throwing
спецификация или нет. Если нет, компилятор предполагает, что
operator new
будет бросать, если нет памяти. Иначе,
он предполагает, что operator new
вернет нулевой указатель. В
ваше дело, ваше operator new
должно быть:
void* operator new( size_t size, unsigned int extra ) throw()
{
//...
}
или если вы можете рассчитывать на поддержку C++11:
void* operator new( size_t size, unsigned int extra) noexcept
{
}