2011-01-22 3 views
3

В 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, то есть в конце концов исключение, а не «проверка». Я говорю о стиле кодирования.

+13

«В C++ мы обычно видим и пишем код типа ...» Нет, мы не делаем. Соответствующая стандартам реализация на C++ должна указывать на ошибки в 'new', вызывая исключение' std :: bad_alloc'. Некоторые старые компиляторы C++ вернули нулевой указатель на ошибку в 'new', но теперь это не так. –

+12

Соответствующее новое в C++ никогда не вернет нулевой указатель. Если вы «обычно видите и пишете код наподобие», вы делаете это неправильно. (Вам нужна форма размещения std :: nothrow new для получения возвращаемого нулевого указателя.) –

ответ

1

новый товар обязательно возможно потертость.

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

5

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

Так эквивалент кода C++ вы должны были бы это:

try { 
    Sample sample = new Sample(); 
} catch(OutOfMemoryException e) { 
    Console.WriteLine("Memory allocation failed\n"); 
} 
14

Согласно 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(); 
+0

не для всех компиляторов: http://stackoverflow.com/questions/550451/will-new-return-null-in-any- case – rve

+8

@rve Я говорю современные компиляторы. VC++ 6 не является современным компилятором. – UmmaGumma

0

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

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

1
  1. я редко вижу его в C++
  2. это не имеет смысла в C#, потому что это просто будет просто выбросить исключение
12

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

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

5
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.

6

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

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

+0

На некоторых несоответствующих компиляторах новый может вернуть NULL. – rve

+0

@rve: на совместимой реализации 'new' никогда не будет возвращать' NULL', если не используется версия 'std :: nothrow'' new'. –

1

В C++ новый может возвращать NULL, когда используется не совместимый компилятор (см Will new return NULL in any case?)

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

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