2017-02-15 27 views
4

Я хочу определить, какой максимальный предел памяти я могу выделить на своем компьютере. Это код, который я написал для этой задачи:как найти максимальный предел распределения памяти в c

#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    int j; 
    int *primes; 
    int i ; 

    int limit = 2147483647; 

    primes = malloc(sizeof(int) * limit); 
    for (i = 0; i < limit; i++) 
    { 
     primes[i] = 1; 
    } 
    return 0; 
} 

Как определить, сколько памяти можно выделить без ударов и испытаний? В этом примере я выделил максимальный размер int. Но программа вылетает из строя. Сколько памяти действительно выделяется в этом примере?

+0

Вы на встроенном аппаратном обеспечении? Если это так, поведение не предсказуемо, см. Http://stackoverflow.com/questions/22422733/malloc-behaviour-on-an-embedded-system – Boern

+7

Во-первых, ваш код неверен. Вы не проверяли успех 'malloc()', поэтому вы не достигаете того, чего хотите. _ «сколько памяти действительно выделяется в этом примере?» _ -> возможно, нет. –

+0

Ваш код не то, что вы хотите. Вы должны выделить куски памяти, например, 1Mb в цикле, пока 'malloc' не вернет' NULL'. Теперь вы знаете (более или менее), сколько памяти вы можете выделить в своей системе. –

ответ

8

malloc()10 разрешено сбой, и в этом случае он возвращает NULL-указатель без выделения памяти. Это всегда все или ничего. Он либо преуспевает, либо выделяет полный фрагмент памяти запрошенного размера, или он терпит неудачу, возвращая NULL-указатель без выделения одного байта.

Что касается знания объема памяти - это действительно зависит от среды: в какой ОС вы работаете, это 16-, 32-, 64-разрядная архитектура памяти?

Например, если вы работаете в Windows 10, вы можете использовать объект GlobalMemoryStatusEx() (см. MSDN:GlobalMemoryStatusEx()).

Linux, OTOH, обеспечивает аккуратный способ получения аналогичной информации. Для получения дополнительной информации см. this page.

Даже если ваша ОС 64-разрядная, что не обязательно означает, что ваше приложение может получить доступ к более чем определенному пределу. Например, 64-разрядная версия Windows 7 позволит вам адресовать до 8 ГБ памяти в код приложения, даже если полное пространство виртуальной памяти составляет 16 ТБ.

+0

Какое использование какое-либо значение, возвращаемое такой функцией, имеет в ОС, где до того, как функция даже возвращает другой процесс, может выделять именно этот объем памяти? И, как правило, нет выбора, сколько требуется памяти. Если это для буферов: оставьте это для ОС и libc. В любом случае, они в большинстве случаев знают лучше. (это может быть иначе для очень специального программного обеспечения, но это все равно не будет записываться новичком) – Olaf

+0

'GlobalMemoryStatusEx()' возвращает (в 'ullAvailVirtual') объем памяти, доступный для ** пользовательского процесса **. Эта память не будет превзойдена другими приложениями пользовательского режима, поскольку они изолированы ** и ** не едят в пространстве памяти друг друга. См. Мой комментарий о Windos 7 в ответе выше (ближе к концу). – YePhIcK

+0

Это подразумевает, что он не может быть выделен ** при любых обстоятельствах **. Если бы Windows не была первой настоящей ясновидящей ОС. Без этого мой комментарий все еще применяется. (префикс «Глобальный» для ограничения ** пользовательского процесса ** довольно пропущен, т. к.). Речь идет не о пространствах памяти (было бы действительно странно, если два процесса имеют одинаковое пространство памяти - исключена разделяемая память). Но, возможно, это то, что DOS-расширитель думает с «двойной памятью в реальном времени», широко распространенной в конце 80-х/начале 90-х годов. Но это были просто змеиное масло. – Olaf

4

Вы код неправильно по многим причинам, как

  • Вы предполагая максимальный размер (для платформы/окружающая среда), которая является наименее вероятно, чтобы быть правдой, меньше быть портативным.
  • Вы при условии, чтоmalloc() предлагает частичного выделения (до доступной памяти) что опять-таки, не так.

    Цитируя C11 стандарт, глава §7.22.3.4 (курсив мой)

    malloc функция возвращает либо пустой указатель или указатель на выделенное пространство.

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

  • Вы не проверяете успех malloc(), что приводит к возможному разыменованию нулевого указателя.

  • Вы не имеете никаких средств на самом деле проверить для успеха/неуспеха распределения

Я считаю, что вы нуждаетесь в getrlimit() и семьи, чтобы достичь своей цели. Особый интерес представляет RLIMIT_DATA как значение resource.

Это говорит,

1. «Я выделил максимальный размер INT в данном примере»

Это, кажется, не быть связано с ограничениями для malloc() и семьи, в любом случае.

2. "Но программа вылетает"

То есть, скорее всего, является результатом undefined behavior.В вашем коде вы прямо разыскиваете возвращаемый указатель, не проверяя успех на malloc(). Вероятно, что malloc() потерпел неудачу и возвратил NULL, разыменование, которое вызывает UB.

+1

Также используется 'int limit = 2147483647;'. Это можно заменить на 'INT_MAX' с' limits.h'. – RoadRunner

+0

@RoadRunner, но это не связано с этой проблемой в руке, верно? это разные пределы, и эта конкретная ценность здесь не представляет интереса, как я ее вижу. –

+0

Я согласен, что-то, о чем может подумать OP. Просто подумал, что я упомянул об этом, так как вы указываете точки в коде OP. – RoadRunner

-1

Есть так много итераций, выполняемых циклом, вы проектируете, что является основными причинами сбоя вашей программы или бесконечной замкнутой петли.

Ответ на то, что вы ожидаете знать очень комплекс из-за некоторых ключевых нот ---- >>

1. Это зависит от платформы, что программа работает на как окна, linux или mac. Я ДУМАЮ, что объем памяти не ограничен ничем, кроме физической памяти.

Факт-> Хотя физическая память может быть расширена виртуальной памятью, не все платформы имеют функцию «виртуальной памяти». C не имеет понятия виртуальной памяти. Malloc выделяет непрерывную память (то есть бок о бок или вместе в ram).
Итак, это зависит от того, как платформа обрабатывает запрос. Это зависит от реализации C.

2. Наибольшее количество (в байтах), представляемое стандартным типом 'size_t' (объявляется). Это значение может и зависит от реализации. Обратите внимание, что это значение не обязательно так велико, как хост (, т. Е. Конечный пользователь) доступная память платформы.

QUES. Есть ли ограничения на это? Где я должен получить этот вид информации?

Ans.Аргумент Malloc - size_t, а диапазон этого типа - [0, SIZE_MAX], поэтому максимально возможный запрос - SIZE_MAX, значение которого варьируется от реализации до реализации и определяется в.

Примечание: - Будет ли запрос для байтов SIZE_MAX успешным, зависит от факторов, выходящих за рамки этой группы.

+1

этот был очень полезно. спасибо –

+0

Mension nt Bhaijan;) Если это действительно полезно @AzamAli, тогда вы можете перенести ан, если вы действительно этого хотите, чтобы это могло быть полезно для других, как вы. :) –

0

Максимальный объем памяти, который вы можете выделить, контролируется несколькими факторами и может меняться со временем.

К ним относятся: 1. ограничения аппаратного обеспечения 2. Ограничения ОС 3. Системные параметры 4. Процесс Квоты 5. Page пространство файл

Кроме того, таНос очень плохой способ выделить крупные блоки памяти.

Ваша программа вылетает из-за того, что malloc возвращает null, и вы используете это возвращаемое значение без проверки.

+0

Я проверил, что malloc вернул NULL, вы правы, поэтому, пожалуйста, дайте мне знать, что я должен сделать, чтобы выделить большой блок, если malloc очень плохо для этого –