Я всегда читаю, что мне не следует бросать std::string
или некоторые другие классы, выделяющие память. например здесь или, что более важно, здесь в пункте 3. - Дон ' t вставить объект std::string
.
Итак, теперь я пытаюсь вставить boost:: exception в мой проект и что я вижу: много строк.
Почему не повышается соответствие его собственной рекомендации?
И если у меня есть параметры, которые не могут быть жестко закодированы, например, безопасно в конфигурационном файле, как я могу помещать их в исключение, не используя std::string
?
Или в руководстве не использовать std::string
только использовать std::string
как можно реже. Я немного смущен...
Я провел некоторое исследование. Пожалуйста, поправьте меня, если я ошибаюсь.
Если я правильно понимаю, все это касается выделения во время броска и того, что происходит с выделенной памятью. Таким образом, память теряется, если я выделяю ее в конструкторе, и она не может быть освобождена в деструкторе исключения, что приведет к утечке памяти. Но это нормально, чтобы выделить это перед бросанием, поэтому исключение чистое.
Я пробовал это:
struct xexception {
int *ttt[10];
xexception() {
ttt[0] = new int[0xfffffffL];
ttt[1] = new int[0xfffffffL];
ttt[2] = new int[0xfffffffL];
ttt[3] = new int[0xfffffffL];
ttt[4] = new int[0xfffffffL];
ttt[5] = new int[0xfffffffL];
ttt[6] = new int[0xfffffffL];
ttt[7] = new int[0xfffffffL];
ttt[8] = new int[0xfffffffL];
ttt[9] = new int[0xfffffffL];
}
~xexception() throw() {
//never happen
delete[] ttt[0];
delete[] ttt[1];
delete[] ttt[2];
delete[] ttt[3];
delete[] ttt[4];
delete[] ttt[5];
delete[] ttt[6];
delete[] ttt[7];
delete[] ttt[8];
delete[] ttt[9];
}
};
int main(int argc, const char *argv[]) {
try {
throw(xexception());
}
catch (const xexception &e) {
std::cerr << "\nttt " << e.ttt[0][0] << std::endl;
}
catch (std::bad_alloc) {
std::cerr << "bad alloc" << std::endl;
}
return 0;
}
В результате получается bad_alloc и огромная утечка памяти.
Теперь, если я делаю выделение раньше, он также выдает bad_alloc, но до создания исключения.
Мое исключение из концепции исключений:
Кому это нужно? Если у меня есть bad_alloc в моей программе, из-за memory_leak или что-то еще (я говорю о программах на ПК, а не о микроконтроллерах), у меня есть другие проблемы. Может быть, я могу понять, что произошел bad_alloc, но где? На моем выделении во время функции (одна из, возможно, 1000) или в std::string
(ну, я знаю, это строка, но... нет возможности манипулировать памятью строки... или ее рассеять).
try {
// where is the error???
int *x = new int[100]; // here?
....
int *y = new int[100]; // or here?
....
int *z = new int[100];
....
int *w = new int[100];
....
int *t = new int[100];
....
int *f = new int[100];
....
std::string str("asdfasdfasdfasdfasdfasdfasdf"); // maybe here
}
catch (the error) {
....
}
А потом? Должен ли я попытаться выяснить, где это происходит? Поэтому я бы использовал valgrind не исключение.
void foo() {
int *i = new int[1];
foo();
}
try {
foo();
}
chatch( bad_boy ) {
go_exception_handler_go(parameters); // oh, shit happens: also an stack_overflow may happend, cause stack is also full
}
Или я должен манипулировать ошибкой и записывать ее, что окончательно выведет следующий bad_alloc.
Пожалуйста, не поймите меня неправильно. Поскольку я видел boost:: exception, я переписал свой класс исключений (до ожидания ответа), но я также думаю, что на самом деле нет необходимости собирать каждый песок.