Почему «long» допускается как длина массива в C #?

Я хотел попытаться выделить массив из 4 миллиардов байтов, и это мой код C #:

long size = 4 * 1000;
size *= 1000;
size *= 1000;
byte[] array = new byte[size];

этот код не работает сSystem.OverflowException на строке, содержащейnew, Ладно получаетсяLength возвращаетсяintТаким образом, длина массива также ограничена тем, чтоint можно хранить.

Тогда почему нет ошибки времени компиляции иlong разрешено использовать как количество элементов массива при выделении?

 konqi08 июн. 2012 г., 10:35
Таким образом, вы выделяете 3,7 ГБ памяти. Сколько оперативной памяти установлено на вашей машине? : D
 Bradley Smith08 июн. 2012 г., 10:34
Array.CreateInstance() дает более значимое сообщение об ошибке: «Массивы размером более 2 ГБ не поддерживаются».
 konqi08 июн. 2012 г., 10:44
Даже пейджинг имеет свои пределы. Предполагая 1024 МБ физической ОЗУ, Windows обычно ограничивает размер файла подкачки 1536 МБ. В совокупности вы сможете выделить 2560 МБ памяти. Поскольку окна устанавливают размер файла верхней страницы равным 1,5-кратному объему физической памяти, я скажу, что физическая память не может быть ограничивающим фактором, но он является фактором.
 sharptooth08 июн. 2012 г., 10:36
@Joso: это 64-битный процесс, поэтому благодаря подкачке страниц он может выделять 3,7 места на диске.
 Joey08 июн. 2012 г., 10:47
JoSo, (а) никто в здравом уме не будет использовать 64-битную Windows только на гигабайте памяти; (б) в наши дни память очень дешева, поэтому все, что меньше 8 ГиБ, в любом случае не имеет смысла; (в) вы читали ответы? Проблема в другом.

Ответы на вопрос(5)

Ответ: долго в .net означает Int64

И индексирование массива может быть Int64 согласно спецификации.

2-й вопрос: почему показывается переполнение?

Потому что ни одному объекту не может быть выделено более 2 ГБ памяти.

 08 июн. 2012 г., 10:59
С такими претензиями (если они не очевидны, например,long быть псевдонимом дляSystem.Int64) всегда приятно подкреплять их ссылками.
 15 февр. 2013 г., 07:01
Я не согласен с вашей второй точкой. Если его недостаточно, вы должны ожидать исключение OutOfMemoryException, а не OverflowException. Согласно спецификации исключение OverflowException следует вызывать только в том случае, если длина меньше нуля.
 16 февр. 2013 г., 06:49
@Joey Возможно, вы правы, но я имею в виду объяснение OverflowException от mdkamruzzaman. В спецификации языка C # говорится, что OverflowException может быть выброшено, если любой спецификатор длины измерения меньше нуля. И это все, это единственная причина. Я не могу найти никакого упоминания в языковой спецификации до предела 2 ГБ. Здесь есть некоторое обсуждение:stackoverflow.com/questions/14889333/…
 15 февр. 2013 г., 07:55
@ Миша: Это не нехватка памяти, просто один объект не может быть больше этого.

Это ограничение CLR, ни один объект не может превышать 2 ГБ, включая массивы:

Большой массив C # OutOfMemoryException

Это не зависит от 32-битных или 64-битных ОС. Тем не менее, это не мешает вам использовать больше, чем эта сумма в целом, только не на одном объекте.

Этоruntime ошибка, потому что если вы сохранитеlong (или другое значение инициализации) в пределах диапазона, это будет работать.

Вы можете инициализировать массивы со всеми целочисленными типами:sbyte, char, short, int, а такжеlong - все компилировать; неподписанные варианты тоже работают.

ссива.

<runtime>
    <gcAllowVeryLargeObjects enabled="true" />
</runtime>

https://msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx

long является целочисленным типом, поэтому его можно использовать для определения массива; Исключением является построение слишком большого массива, а не использованиеlong.

Отлично, это работает просто отлично:

long size = 20;
byte[] array = new byte[size];
Решение Вопроса

Поскольку спецификация говорит об этом в разделе 7.6.10.4:

Each expression in the expression list must be of type int, uint, long, or ulong, or implicitly convertible to one or more of these types.

Это скорее всего легкоallow создание массивов размером более 2 ГиБ, даже если они не поддерживаютсяyet (но будет безlanguage изменить, как только CLR сделает такое изменение).Mono поддерживает это, однако а также.NET 4.5, по-видимому, тоже позволит большие массивы.

Что касается длины массива, являющегосяint кстати: есть такжеLongLength, возвращаяlong, Это было в .NET 1.1 и, вероятно, изменение будущего.

 08 июн. 2012 г., 12:44
В самом деле. Тогда вы могли бы сделать это многомерным массивом, чтобы обойти это. Но это тоже противно.
 08 июн. 2012 г., 10:42
+1 Хорошее место на 4.5 материале, надеюсь, Бог, я никогда не вижу, что включено в нашем приложении ...
 15 февр. 2013 г., 06:58
@ ErenErs & # xF6; nmez вы написали & quot; он говорит ... & quot; Где это сказано?
 15 февр. 2013 г., 07:54
@Mishax: Во вторую ссылку я включил в свой ответ.
 08 июн. 2012 г., 12:42
Похоже, что даже с изменением 4.5 рассматриваемый код все равно потерпит неудачу, потому что он говорит: «Максимальный индекс в любом одном измерении равен 2 147 483 591 (0x7FFFFFC7) для байтовых массивов и массивов однобайтовых структур и 2 146 435 071 (0X7FEFFFFF) для других». типы & Quot.

Ваш ответ на вопрос