новое никогда не подведет? - PullRequest
3 голосов
/ 22 января 2011

В C ++ мы обычно видим и пишем код, подобный

Sample sample=new Sample();
if ( sample == NULL )
{
     std::cout<<"Memory allocation failed" << std::endl;
}

Но в C # я редко вижу это: (по крайней мере, я никогда не видел этого)

Sample sample = new Sample();
if ( sample == null )
{
     Console.WriteLine("Memory allocation failed\n");
}

Значит, в C # мы редко проверяем , если new не удалось или нет.Почему это так?Это как-то связано с «В C # новое никогда не перестает работать» ?Есть ли такая вещь в C #, что new никогда не выходит из строя?

Если она терпит неудачу, то почему такая «проверка» так редко встречается в C #?Я не говорю о OutOfMemoryException, то есть, в конце концов, исключение , а не "проверка".Я говорю о стиле кодирования.

Ответы [ 10 ]

14 голосов
/ 22 января 2011

По данным MSDN

Если новый оператор не может выделить память, он генерирует исключение OutOfMemoryException.

http://msdn.microsoft.com/en-us/library/51y09td4%28v=vs.71%29.aspx

Кстати, только старые компиляторы C ++ возвращают 0 при попытке выделить память. Современные бросают исключение std :: bad_alloc. Если вы хотите старого поведения, вам нужно написать

Sample sample=new(std::nothrow) Sample();
12 голосов
/ 22 января 2011

В C # new выдает OutOfMemoryException, если это не удается, поэтому проверка NULL не требуется.

Кстати, то же самое относится и к C ++ - new выдает std::bad_alloc в случае неудачи, так что действительно нет необходимости проверять NULL в C ++.

6 голосов
/ 22 января 2011

В C ++, в отличие от malloc, new не возвращает NULL при сбое.Фактически, он выдает исключение std::bad_alloc при сбое.

Если вы хотите, чтобы new вернул NULL при сбое, вы должны явно сказать ему, чтобы оно не выкидывало исключение.Для этой цели используйте версию std::nothrow.(заголовочный файл: <new>)

5 голосов
/ 22 января 2011
Sample sample=new Sample();
if ( sample == NULL )
{
     // You will never get here!
     std::cout<<"Memory allocation failed" << std::endl;
}

Мы также не пишем это на C ++."Memory allocation failed" никогда не появится.На обоих языках вы получите исключение, если выделение не удастся.В C ++ это std::bad_alloc, в C # это OutOfMemoryException.

5 голосов
/ 22 января 2011

Если new завершится неудачей, будет выдано OutOfMemoryException.

Таким образом, эквивалентный код C ++, который у вас есть, будет таким:

try { 
  Sample sample = new Sample();
} catch(OutOfMemoryException e) {
  Console.WriteLine("Memory allocation failed\n");
}
1 голос
/ 22 января 2011

В C ++ new может возвращать NULL при использовании несовместимого компилятора (см. Будет ли new возвращать NULL в любом случае? )

Но правильный подход в C ++ состоит в том, что newвыдает исключение при нехватке памяти, как в C #.

Проверка на NULL необходима только для определенных компиляторов.

1 голос
/ 22 января 2011
  1. Я редко вижу это в C ++
  2. Это не имеет смысла в C #, потому что оно просто выдаст исключение
1 голос
/ 22 января 2011

В C #

есть исключение OutOfMemoryException
1 голос
/ 22 января 2011

новый может конечно потерпеть неудачу.

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

0 голосов
/ 22 января 2011

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

Тем не менее, вы, безусловно, можете исчерпать память, если выделите достаточно памяти и сохраните ссылки на нее (в этот момент будет выдано исключение - указатель NULL в качестве возвращаемого значения для выделения памяти более распространен в C, и в версиях C ++, написанных для игровых приставок.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...