@sabn1k
Возможно я написал чепуху, но попытайтесь понять

Как заставить сработать исключение std::bad_alloc?

В книге одна страница уделена исключению bad_alloc и приведен такой пример:
typedef unsigned long ULONG;
int main()
{
	setlocale(0, "");
	const ULONG SIZE = 10200;
	char* ptr;
	try
	{
		ptr = new char[SIZE];
	}
	catch (std::bad_alloc)
	{
		std::cout << "\n Исключение bad_alloc: невозможно разместить данные в памяти.\n";
	}
	delete[] ptr;
	std::cout << "\nПамять используется без сбоев.\n";
	getch();
	return 0;
}

Что мне необходимо поменять или добавить, чтобы сработало исключение? Просто самому интересно, в каком случае происходит переполнение.
  • Вопрос задан
  • 1188 просмотров
Решения вопроса 1
@Mercury13
Программист на «си с крестами» и не только
#include <iostream>
#include <conio.h>

int main()
{
  setlocale(LC_ALL, "Russian");
  const size_t SIZE = 3000000000ul;
  char* ptr = NULL;
  try
  {
    ptr = new char[SIZE];
    std::cout << "Память используется без сбоев.\n";
  }
  catch (std::bad_alloc&)
  {
    std::cout << "Исключение bad_alloc: невозможно разместить данные в памяти.\n";
  }
  delete[] ptr;
  getch();
  return 0;
}


Столько кода — и столько ошибок! По пунктам.
1. Ответ на ваш вопрос. Сделать константу побольше. Кстати, эта константа — size_t. В 64-битном коде надо ещё больше.
2. Не проработано поведение delete[], если случится ошибка. Покатит инициализация NULL.
3. Если случится ошибка, будут выведены оба сообщения.
4. getch — функция из платформозависимого заголовка conio.h. Только DOS/Windows.
5. Обработку аварий обычно делают по ссылке.
6. Для первого параметра setlocale надо указывать ненулевую маску, на какие части ставить локаль. LC_ALL — везде. Что писать вторым параметром, зависит от библиотеки времени выполнения.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@MiiNiPaa
Я напишу ответы на вопросы в комментариях здесь:

А system("pause") платформонезависимый?
Нет
Ведь программа сразу же закрывается. Или како-то это по другому решается?
Настройте IDE нормально, либо запускайте программы из командной строки, а не двойным щелчком. Это нормальное и правильное поведение для консольных программ.
Ссылка используется только в случае с std::bad_alloc или с классами тоже?
Стандарт обработки исключений в С++: бросать по значению, ловить по ссылке.
То есть, такого типа указатели нужно всегда инициализировать? Если не char* ptr = new char[SIZE], то char* ptr = NULL и на другой строке ptr = new char[SIZE]?
Если char* ptr = new char[SIZE] бросит исключение, то переменной ptr не существует и удалять нечего. Нужно всегда инициализировать переменную при объявлении. Чем — другой вопрос.

И да, на современных системах единственный гарантированный способ получить bad_alloc — истощить адресное пространство программы. И убедится, что компилятор не выкинет выделение памяти как ненужное. Проще кинуть bad_alloc самомтоятельно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы