C ++ bad_alloc исключение - PullRequest
       2

C ++ bad_alloc исключение

4 голосов
/ 19 января 2012

Я пытаюсь поймать исключение bad_alloc, чтобы доказать, что используются деструкторы.

Вот мой объект:

#include "Obj.h"
#include<iostream>
using namespace std;

Obj::Obj() {
d = new double[200000000];
}
Obj::~Obj() {
cout << "destroyed \n";
}

И основной метод:

#include "Obj.h"
#include <iostream>
using namespace std;
int main(){
Obj* ptr[1000000];
try{
    for(int i=0; i<1000; i++){
        ptr[i] = new Obj();
    }
} catch(bad_alloc){
    cout<<"EXCEPTION";
}
}

Вместо того, чтобы поймать исключение, моя программа останавливается и пытается найти решение онлайн (Windows). Почему это происходит?

EDIT Теперь я получаю исключение, но я должен доказать, что деструктор используется ДО создания исключения. Как мне это сделать?

Ответы [ 3 ]

8 голосов
/ 19 января 2012

Проблема возникает еще до того, как вы начнете динамически распределять объекты.Если вы запустите программу с подключенным отладчиком, вы увидите, что программа завершается из-за переполнения стека.Почему?

Obj* ptr[1000000];

Невозможно объявить такой большой объект с автоматической продолжительностью хранения.Когда вводится main, он пытается выделить место в стеке для этого объекта и не может этого сделать, что вызывает структурное исключение переполнения стека.Ваше приложение не обрабатывает это исключение, поэтому среда выполнения завершает программу.

Обратите внимание, однако, что деструктор Obj никогда не будет вызываться вашей программой.Когда вы динамически выделяете объект с помощью new, вы несете ответственность за его уничтожение с помощью delete.Поскольку вы никогда не вызываете delete для уничтожения созданных вами объектов, они никогда не уничтожаются.

Если бы вы использовали, скажем, std::vector<std::unique_ptr<Obj>> вместо (или, в этом отношении, просто std::vector<Obj>), вы бы увидели, что деструктор будет вызываться для каждого полностью созданного Objобъект.

4 голосов
/ 19 января 2012

Имейте в виду, что вы пытаетесь сохранить очень большой массив в стеке с вашим массивом ptr ... скорее всего, ваша проблема в том, что вы переполнили размер стека, выделенный для вашего приложения до тогоoperator new может завершиться с ошибкой за исключением нехватки памяти.

1 голос
/ 19 января 2012

Я вставил весь ваш код в файл, немного увеличил целочисленную константу, завершил определение класса для Obj и перезапустил ваш код с некоторой отладкой. На 64-битном Unix-сервере он правильно выводит «исключение» при попытке выполнить конструктор Obj.

#include<iostream>
using namespace std;

struct Obj {
Obj() {
d = new double[20000000000000000LL];
}
~Obj() {
cout << "destroyed \n";
}

double* d;
};

int main(){
Obj* ptr[1000000];
try{
    for(int i=0; i<1000; i++){
        ptr[i] = new Obj();
        cout<<"bah!"<<endl;
    }
} catch(bad_alloc){
    cout<<"EXCEPTION";
}
cout<<"Done."<<endl;
}

[jhumphreys@suoserv ~]$ g++ so2.cpp
[jhumphreys@suoserv ~]$ ./a.out
EXCEPTIONDone.
[jhumphreys@suoserv ~]$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...