Самая короткая программа, которая постоянно выделяет память


49

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

Многие ядра на самом деле не зарезервируют память, которую вы выделяете, пока не используете ее для чего-то, поэтому, если ваша программа написана на C или каком-либо другом низкоуровневом языке, вам нужно будет обязательно что-то написать для каждой страницы. Если вы используете интерпретированный язык, вам, вероятно, не придется беспокоиться об этом.

Самый короткий код выигрывает.


13
Является ли переполнение стека верным решением? Должна ли быть утечка памяти или просто выделена?
Wheat Wizard

1
@WheatWizard Память не должна вытекать, но она должна выделяться быстрее, чем она освобождается.
tbodt

2
Один раз, когда я хочу, чтобы моя программа потребляла бесконечную память, я не могу ее получить. (reduce conj [] (range))(Clojure) получает до 737mb, а затем просто перестает расти. Я думаю, что это не постоянно идет вверх. Он «думает», что я хочу напечатать весь список в конце, поэтому он не должен ничего выбрасывать. Очень расстраивает.
Carcigenicate

14
Примечание для себя: сохраните код перед тестированием. Внедрение mem-leaks может привести к краху IDE ...
steenbergh

1
Я думаю, что вы должны добавить еще одну проблему в гольф, похожую, но отдельную, требующую, чтобы программа потребляла память быстрее, чем линейная функция времени. Для текущей задачи хорошо работать циклически и выделять один байт. Для вашей новой задачи этого было бы недостаточно, но с циклом навсегда и удвоением объема используемой памяти каждый раз было бы неплохо.
Бен Голдберг

Ответы:


46

Funge-98 ( cfunge), 1 байт

9

Я бы опубликовал это раньше, но решил протестировать его, и потребовалось некоторое время, чтобы вернуть мой компьютер в рабочее состояние. cfungeхранит стек Funge в куче операционной системы (которую легко проверить, запустив программу с небольшим ограничением памяти, что я и должен был сделать раньше!), таким образом, бесконечно растущий стек (как с этой программой, которая просто выдвигает 9несколько раз; Программы Funge, перенесенные с конца строки на начало по умолчанию, будут выделять память навсегда. Эта программа, вероятно, также работает в некоторых реализациях Befunge-93.

Интереснее:

"NULL #(4

Это была моя первая идея, и она представляет собой бесконечное распределение, которое не зависит от стека Funge (хотя оно также разрушает стек Funge). Для начала, "команда помещает копию остальной части программы в стек (это строка, и программа оборачивается, поэтому закрывающая кавычка также служит открытой кавычкой). Затем Nотражается (по умолчанию это не имеет смысла), вызывая запуск программы в обратном направлении. В "пробеги снова, и толкает программу в стек - наоборот это время, с Nна вершине стека - то программа обтекает, загружая библиотеку с именем 4-буквенного ( 4(, а NULLбиблиотека является частью cfungeстандартная библиотека). NULLопределяет все заглавные буквы , чтобы сделать отражать, так что Lотражает, то#скачет библиотеки нагрузки на пути обратно, 4выталкивает барахло мы не заботимся о том, чтобы стек и всей программе повторяется с самого начала. Учитывая, что загрузка библиотеки несколько раз имеет эффект, и требует, чтобы список команд библиотеки хранился один раз для каждой копии библиотеки (это подразумевается семантикой Funge-98), это приводит к утечке памяти через не стековое хранилище (которое является альтернативный метод определения «кучи», относительно языка, а не ОС).


2
Я просто собираюсь принять это ...
tbodt

Нужно ли, чтобы число было 9? Будет ли это работать, если это было 5?
tbodt

Все, что выталкивает в стек, работает (кроме, возможно 0, возможно, что реализация Funge или ОС могли бы найти способ оптимизировать это, учитывая, что рассматриваемая память уже заполнена нулями). Я просто выбрал 9произвольно.

22
Это неприемлемо, потому что я хочу, чтобы моя репутация оставалась 666.
tbodt

7
@tbodt Не реальная причина не принимать. Если хотите, я отвечу на ваш вопрос. Затем, когда вы примете, у вас будет еще 703 (обратите внимание, у вас сейчас 703, а не 666).
NoOneIsHere

30

Brainfuck, 5 байтов

+[>+]

Для этого требуется переводчик, который не имеет ограничений по длине ленты.


2
Я уверен, что это + [> +], иначе он просто остановится на первой итерации. ;)
Пэрис Дуади

Вы правы, извините за опечатку.
VSZ

40
Один из редких случаев, когда решение для
мозгового безумия

@ Flp.Tkc Но все равно проигрывает. Может быть, он когда-нибудь победит ...
NoOneIsHere

6
@SeeOneRhino: он уже однажды выиграл, обыграв все языки игры в гольф> codegolf.stackexchange.com/questions/8915/…
vsz

22

Bash + coreutils, 5

или же

Руби, 5

`yes`

yesпроизводит бесконечный выход. Задание yesобратных галочек говорит оболочке перехватить весь вывод и затем выполнить этот вывод как команду. Bash продолжит выделять память для этой бесконечной строки, пока не закончится куча. Конечно, в результате вы получите недопустимую команду, но мы должны исчерпать память, прежде чем это произойдет.

Спасибо @GB за указание, что это полиглот и в рубине.


7
Я собирался написать то же самое и назвать это программой Ruby.
GB

1
и Perl, я думаю.
abligh

18

Python, 16 байт

Сохраняет вложение, aпока не будет достигнута ошибка:

a=0
while 1:a=a,

Первые несколько итераций (в виде кортежей) выглядят так:

0
(0,)
((0,),)
(((0,),),)

и так далее и тому подобное.


18

> <> (Рыба), 1 байт

0

Попробуй это здесь!

0 может на самом деле заменить любое шестнадцатеричное число 1-е.

объяснение

0in> <> просто создает кодовое поле 1x1, в котором рыба может плавать. Она постоянно добавляет 0в стек, плавает вправо, что делает возврат в обратном направлении 0, снова добавляя его в стек. Это будет продолжаться вечно.


2
Теперь мне интересно, на скольких других двухмерных языках это работает. В конце концов, большинство из них основано на стеке.

1
Почти работает в Cubix , но .для перемещения 0в строку исполнения требуется ведущий (или любой непробельный символ) .
ETHproductions

1
Работает в Уроборосе , но не так: интерпретатор пытается читать 0000000...как один целочисленный литерал, и строящаяся строка - это то, что продолжает занимать больше памяти. Программа, которая работает так же, как и эта a(бесконечно толкает 10).
DLosc

12

Java 101 байт

class A{public void finalize(){new A();new A();}public static void main(String[]a){for(new A();;);}}

Поймать основную программу в бесконечном цикле после создания и отбрасывания объекта. Сборка мусора выполняет утечку, создавая 2 объекта для каждого удаленного


ну, я чувствую себя немного глупо из-за того, что не пойду с очевидным сейчас, хаха. Рискну сказать, что это более элегантно, чем у меня
Poke

1
да, ваш код вспомнил меня об этом с помощью finalize () @poke
masterX244

Я думаю, что вы могли бы сделать его короче, заменив main статическим инициализатором
tbodt

работает только до java6 и у меня только более высокие версии
masterX244

2
ха-ха, используя сборщик мусора, чтобы вызвать утечку! отличная идея :)
Марк К Коуэн

12

Perl, 12 байт

{$"x=9;redo}

В Perl xоператор со строкой слева и числом справа создает повторяющуюся строку. Так "abc" x 3оценивает "abcabcabc".

x=Оператор мутирует левый аргумент, заменяя содержимое переменной на ее слева, в результате повторения его содержание , как много раз , как его правая рука указывает.

В Perl есть ряд встроенных переменных со странным именем, одна из которых $", чье начальное значение - один пробел.

redoОператор переходит к началу ограждающих {}.

В первый раз, когда x=оператор выполняется, он меняет значение $"с " "«на» " ", что составляет 9 пробелов.

Во второй раз, когда x=оператор выполняется, он меняет значение $"на " ", которое составляет 81 пробел.

В третий раз $"получается строка длиной 729 байт.

Я думаю, что вы можете видеть, куда это идет :).


Ты подтолкнул меня на это! А у тебя на три байта короче.
Габриэль Бенами

1
Это был просто вопрос поиска этого веб-сайта для наименьшего цикла :). Кроме того, у меня изначально был $_.=7цикл, но я понял, что если бы я мог x=его использовать, мне бы хватило бы памяти, а затем побежал, perldoc perlvarчтобы выбрать что-то подходящее.
Бен Голдберг

{$^O++;redo}на один байт короче, когда ^Oодин chr(15)байт. Хотя он будет тратить память НАМНОГО медленнее - 1000000000 итераций требуются в Windows, чтобы тратить один байт. Будет работать на любой ОС, название которой начинается с латинской буквы.
Олег Васильевич Волков

11

sed, 5 байт

Golfed

H;G;D

Использование (любой вход будет делать)

sed 'H;G;D' <<<""

Разъяснения

#Append a newline to the contents of the hold space, 
#and then append the contents of the pattern space to that of the hold space.
H

#Append a newline to the contents of the pattern space, 
#and then append the contents of the hold space to that of the pattern space. 
G

#Delete text in the pattern space up to the first newline, 
#and restart cycle with the resultant pattern space.
D

Скриншот

введите описание изображения здесь

Попробуйте онлайн!


2
Строго говоря, это GNU sed (точка с запятой не является стандартным sed), но новая строка будет работать так же хорошо, как и точка с запятой в любом случае.
R ..

10

Haskell, 23 19 байтов

main=print$sum[0..]

Распечатать сумму бесконечного списка


Это хороший способ обеспечить оценку, и он очень компактен. +1
Esolanging Fruit

компилятор может очень хорошо запустить это в O (1) памяти. В GHC sumопределяется как foldl (+) 0, и что должно помешать анализу строгости, чтобы предотвратить выброс толчка? Вы запускали его с оптимизацией?
Уилл Несс

@WillNess Что может быть ответом? sumзаранее не узнаю, что список бесконечен и printв сумме он должен быть оценен первым. И да, я скомпилировал его с оптимизацией
Angs

не было бы ответа; но расчет будет выполняться в пространстве O (1). К сожалению, из-за значения Integerпо умолчанию числа не ограничены, и память, занятая текущим результатом bignum , действительно будет расти.
Уилл Несс

1
просто чтобы уточнить, что я имел в виду, что вычисление sum xs = foldl (+) 0 xsможет выполняться в постоянном стеке, как любой императивный цикл . foldl' (+) 0 xsконечно будет. Таким образом, единственное, что выделяет память наверняка, это промежуточный результат bignum.
Уилл Несс

9

C ++ (с использованием компилятора g ++), 27 23 15 байт

Спасибо Neop за помощь в удалении 4 байтов

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

main(){main();}

Альтернативное решение

Это решение на самом деле утечки памяти.

main(){for(;;new int);}

Выход Valgrind

Это вывод Valgrind после завершения программы через несколько секунд после запуска. Вы можете видеть, что это, безусловно, утечка памяти.

==2582== LEAK SUMMARY:
==2582==    definitely lost: 15,104,008 bytes in 3,776,002 blocks
==2582==    indirectly lost: 0 bytes in 0 blocks
==2582==      possibly lost: 16 bytes in 4 blocks
==2582==    still reachable: 4 bytes in 1 blocks
==2582==         suppressed: 0 bytes in 0 blocks

3
Название вводит в заблуждение; вопрос гласит «написать программу, которая работает вечно и постоянно выделяет память».
NobodyNada - Восстановить Монику

О, я не понял, что вы уже представили ответ, когда я отправил мой.
Неоп

1
@ Нет, ну, я не знал, что ты можешь пропустить, int пока я не увидел твои, так что спасибо!
Пшеничный волшебник

2
Нет C++, просто диалект g ++: C ++ запрещает вызывать main; C ++ требует int main...объявления. Но решение все еще опрятно :-)
Martin Ba

1
Действительно, C ++ запрещает звонить main.
R ..

9

ЯВА, 81 79 78 байт

JAVA (HotSpot) 71 70 байт

Короче, чем другие ответы Java на момент публикации (81, позднее 79 байт):

class A{public static void main(String[]a){String x="1";for(;;)x+=x.intern();}}

По предложению @Olivier Grégoire можно сохранить еще один байт:

class A{public static void main(String[]a){for(String x="1";;)x+=x.intern();}}

Размещение x+=x.intern()в качестве приращения цикла for ничего не поможет, потому что точка с запятой все еще требуется для завершения оператора for.

Как предлагает @ETHproductions, x+=xтоже просто работает работает:

class A{public static void main(String[]a){String x="1";for(;;)x+=x;}}

Который может также извлечь выгоду из подсказки @Olivier Grégoire:

class A{public static void main(String[]a){for(String x="1";;)x+=x;}}

Мое единственное опасение по этому поводу состоит в том, что не гарантируется выделение данных в куче , поскольку эффективная JVM может легко понять, что xникогда не ускользнет от локальной функции. Использование intern()позволяет избежать этой проблемы, потому что интернированные строки в конечном итоге хранятся в статическом поле. Однако HotSpot генерирует OutOfMemoryErrorдля этого кода, так что я думаю, что все в порядке.

Обновление: @Olivier Gregoire также отметил, что x+=xкод может работать, StringIndexOutOfBoundsExceptionа не OOMкогда много памяти доступно. Это потому, что Java использует 32-битный intтип для индексации массивов (а строки - это просто массивы char). Это не влияет на x+=x.intern()решение, так как память, необходимая для последнего, является квадратичной по длине строки и, следовательно, должна увеличиваться до порядка 2 ^ 62 выделенных байтов.


Добро пожаловать в PPCG! Я не очень хорошо знаю Java; что случилось бы, если бы вы только что сделали x+=x;?
ETHproductions

Вы можете сбрить точку с запятой, поставив x+=x.intern()последнюю точку с запятой в цикле for
masterX244

Хороший ответ. Я знал, что должно быть что-то со струнами, internно я был очень счастлив с Unsafe и решил, что перестал искать, хаха. Первоначально этот вопрос указывал на «утечку памяти», поэтому я не просто ответил на строку.
Тыкни

Если ваш ответ зависит от конкретной реализации Java и не обязательно будет переносимым на все реализации Java, вы можете поместить информацию в заголовок (например # Java (HotSpot), 71 bytes). Таким образом, вам не нужно беспокоиться о возможном мошенничестве; специфичные для реализации программы распространены не только в гольфе, но и в более широком мире программирования, и если вы знаете, что делаете, иногда может быть более подходящим, чем портативная программа, скажем, для вне сценария.

1
хм ... x+=x;не исчерпывает всю память. С 64 ГБ я получаю StringIndexOutOfBoundsException, а не ООМ. С .intern()я все еще получаю OOM.
Оливье Грегуар

8

Perl 6 , 13 байт

@= eager 0..*

Объяснение:

@ = сохранить результат в безымянный массив

eager сделать следующий список нетерпеливым

0 .. * бесконечный диапазон, начинающийся с нуля



6

Python 3, 16 байт

i=9
while 1:i*=i

Это связано с тем, что в Python 3 нет ограничений на целочисленный размер; вместо этого целые числа могут занимать столько памяти, сколько может обработать система (если что-то в моем понимании этого неверно, исправьте меня).


Название подразумевает, что память должна быть утечка. Но на самом деле это не утечка памяти. Автор, наверное, должен уточнить.
Wheat Wizard

6

Ржавчина, 46 байт

fn main(){loop{std::mem::forget(Box::new(1))}}

Заметили что-нибудь интересное в этой программе Rust, утечка выделений кучи до нехватки памяти?

Это верно, нет небезопасного блока. Rust гарантирует безопасность памяти в безопасном коде (без чтения неинициализированных данных, чтения после освобождения, двойного освобождения и т. Д.), Но утечки памяти считаются совершенно безопасными. Есть даже явная функция, которая заставит компилятор забыть об очистке RAII от переменных вне области видимости, которые я здесь использую.


6

TI-83 Hex Assembly, 7 байтов

PROGRAM:M
:AsmPrgm
:EF6A4E
:C3959D
:C9

Создает appvars бесконечно, пока ERR:MEMORYОС не выбрасывает их. Беги с Asm(prgmM). Я считаю каждую пару шестнадцатеричных цифр одним байтом.


6

Python, 8 байт

2**9**99

О.П. позволило техничность программы , которая технически не запустить «навсегда», но выделяет больше памяти , чем любой компьютер мог справиться. Это не совсем googolplex (то есть 10**10**10011 байт), но наивно, лог-база 2 числа

>>> 9**99.
2.9512665430652752e+94

то есть, 10 ^ 94 бит, чтобы представить это. Вольфрам Альфа считает, что это на 10 ^ 76 больше, чем глубокая паутина (имейте в виду, что во вселенной около 10 ^ 80 атомов ).

Почему 2 вместо 9 ты спрашиваешь? Это не имеет большого значения (использование 9 увеличит количество битов только в два раза log2(9) = 3.2, что не изменит показатель степени). Но с другой стороны, программа работает намного быстрее с 2, так как расчет проще. Это означает, что он немедленно заполняет память, в отличие от версии 9, которая занимает немного больше времени из-за необходимых вычислений. Не обязательно, но приятно, если вы хотите «проверить» это (что я и сделал).


5

Желе , 3 2 байта

-1 байт благодаря Денису ( Wобертывания)

Ссылка (то есть функция или метод), которая также работает как полная программа, которая рекурсивно оборачивает свои входные данные в список.

Входные данные начинаются с нуля, поэтому первый проход создает список. [0]
Затем второй проход делает это [[0]]
. Третий проход делает это [[[0]]]
и так далее ...


Предыдущие 3 байта, которые протекают намного быстрее:

;Ẇß

рекурсивно объединяет все непустые смежные подсписки своего ввода с его вводом.
[0]-> [0,[0]]-> [0,[0],[0],[[0]],[0,[0]]]и так далее ...


Если я правильно понимаю правила, ‘ßдолжно быть много.
Деннис

Действительно ли это «постоянно выделяет память» (думая о том, чтобы Python сохранял постоянное распределение для маленьких целых).
Джонатан Аллан

1
Справедливо. должен все же соответствовать счету все же.
Деннис

5

Java 7, 106 байт

class A{public void finalize(){for(;;)Thread.yield();}public static void main(String[]a){for(;;)new A();}}

Меньше гольфа

class A{
    @Override
    public void finalize(){
        for(;;) {
            Thread.yield();
        }
    }
    public static void main(String[]a){
        for(;;){
            new A();
        }
    }
}

finalizeМетод вызывается для объекта сборщиком мусора , когда сборка мусора определяет , что больше нет ссылок на объект. Я просто переопределил этот метод, чтобы он зациклился навсегда, чтобы сборщик мусора никогда не освобождает память. В mainцикле я создаю новые объекты, которые никогда не будут очищены, поэтому в конечном итоге это израсходует всю доступную память.

Java 7 (забавная альтернатива), 216 байт

import sun.misc.*;class A{public static void main(String[]a)throws Exception{java.lang.reflect.Field f=Unsafe.class.getDeclaredField("theUnsafe");f.setAccessible(1>0);for(;;)((Unsafe)f.get(null)).allocateMemory(9);}}

Меньше гольфа

import sun.misc.*;
class A{
    public static void main(String[]a)throws Exception{
        java.lang.reflect.Field f=Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe u = (Unsafe)f.get(null);
        for(;;) {
            u.allocateMemory(9);
        }
    }
}

Это весело больше всего на свете. Этот ответ использует Unsafeбиблиотеку Sun, которая является недокументированным внутренним API. Возможно, вам придется изменить настройки компилятора, чтобы разрешить API с ограниченным доступом. Unsafe.allocateMemoryвыделяет определенное количество байтов (без какой-либо проверки границ), которые не находятся в куче и не находятся под управлением java-сборщика мусора, поэтому эта память будет сохраняться до тех пор, пока вы не вызовете Unsafe.freeMemoryили пока jvm не исчерпает память


1
Интересно, увижу ли я здесь Java?
Волшебная Урна Осьминога

Разве первый не работает, только если сборщик мусора работает в отдельном потоке?
tbodt

@ tbodt да, но я не верю, что это никогда не так. Сборка мусора происходит в потоке демонов, называемом сборщик мусора
Poke

@ Poke это гарантировано? если нет, ответ все еще в порядке, но вы должны уточнить, что он работает, только если сборщик мусора работает в своем собственном потоке
tbodt

@ tbodt Я так думаю, но я не уверен, если честно.
Тыкни

5

Haskell, 24 байта

f x=f$x*x
main=pure$!f 9

Основная проблема в Haskell - победить лень. mainдолжен иметь какой-то IOтип, поэтому простой вызов main=f 9не будет работать. Использование main=pure(f 9)поднимает тип f 9к IOтипу. Однако использование таких конструкций, как main=pure 9ничего не делает, 9возвращается или отображается нигде, а просто отбрасывается, поэтому нет необходимости оценивать аргумент pure, следовательно main=pure(f 9), не вызывает выделение какой-либо памяти, как fэто не вызывается. Для обеспечения оценки $!оператор существует. Он просто применяет функцию к аргументу, но сначала оценивает аргумент. Таким образом, использование main=pure$!f 9оценивает fи, следовательно, постоянно выделяет больше памяти.


После компиляции среда выполнения обнаруживает цикл и прерывает выполнение
Angs

@Angs Я скомпилировал с GHC на Windows, и он продолжает счастливо распределять память ... Я остановил его на 3 ГБ.
Лайкони

Использование f x=f xтоже работает, верно? (-2 байта)
wchargin

@wchargin Я так не думаю, f x=f xсоздает бесконечный цикл, но без выделения новой памяти.
Лайкони

Здорово, что вызвало взрыв памяти с помощью вычислений bignum! f!x=x*f(x*x)должен сделать это оптимизационным доказательством.
Уилл Несс

5

постоянный ток, 7 байтов

[ddx]dx

[ddx]толкает строку, содержащую «ddx» в стек. dxдублирует его, затем выполняет его как код (оставляя одну копию в стеке). При выполнении он создает две копии, затем выполняет одну, оставляя еще одну копию в стеке каждый раз.


Подождите, так что это будет экспоненциально распределять память, если она может работать параллельно?
HyperNeutrino

5

Haskell (использует ghc 8.0.1), 11 байт

m@main=m>>m

Нехвостая рекурсия. mainназывает себя, а потом снова себя.


Это распределяется в куче или стеке? (Я могу в это поверить; это вполне может зависеть от используемого компилятора Haskell.)

1
@ ais523: это зависит. У Haskell нет стека вызовов . Система RTS времени выполнения имеет область памяти для сопоставления с образцом, которая также называется «стеком». Этот стек расположен в куче. Честно говоря, я не знаю, что здесь происходит, потому что сбой программы с Stack space overflow: current size 33624 bytes.33k кажется довольно низким в отличие от 6G общего объема памяти, о котором сообщает ОС.
Ними

1
@ ais523: в информации о памяти сообщения об ошибке ghc, похоже, есть ошибка , поэтому трудно сказать, что именно происходит.
Ними

Скомпилированный на GHC 7.10.3 в Ubuntu, кажется, что он занимает постоянный объем памяти, даже когда оптимизации отключены
Angs

@Angs: хм, я использую ghc 8.0.1 на MacOS. Я отредактирую это.
Nimi

5

C (linux), 23 байта

main(){while(sbrk(9));}

sbrk()увеличивает верхнюю часть сегмента данных на заданное количество байтов, тем самым эффективно увеличивая объем памяти, выделенной программе - по крайней мере, как указано в VIRTполе topвывода. Это работает только в Linux - реализация macOS, по-видимому, является эмуляцией, которая позволяет выделять только до 4 МБ.


Итак, немного более общий ответ:

C, 25 байтов

main(){while(malloc(9));}

Я смотрел это на мониторе активности MacOS. До 48 ГБ, а затем процесс получил сигнал SIGKILL. FWIW мой MacBook Pro имеет 16 ГБ. Большая часть используемой памяти была сообщена как сжатая.

Обратите внимание, что этот вопрос фактически требует записи каждого выделения, что здесь явно не происходит. Однако важно отметить, что для каждого malloc(9)вызова выделяются не только 9 запрошенных пользователем байтов. Для каждого выделенного блока будет заголовок malloc, который также выделяется где-то в куче, что обязательно записывается malloc()внутренними компонентами.


С malloc вы не пишете напрямую в память, так как malloc ничего не инициализирует. Память выделяется только потому, что malloc требуется некоторое внутреннее хранилище для управления памятью. Так что ответ на самом деле не стандартный, но я думаю, он все равно работает везде.
Анци

@Анци Да. Тем не менее, я думаю, что это все еще работает, потому что, хотя пользовательская память может фактически не выделяться до того, как она будет записана, каждый malloc()блок ed должен по-прежнему иметь свое собственное реальное выделенное пространство. Это работает на macOS и Ubuntu.
Цифровая травма

Условие в вопросе о каждой странице, на которую пишут, довольно бессмысленно; даже если вы хотите предположить, что ОС не выполняет надлежащий учет фиксации, независимо от деталей реализации, для каждого выделения обязательно потребуется ненулевое количество счетов. Независимо от того, находится ли он рядом с распределением (вызывая прикосновение к страницам) или нет, он в конечном итоге потребляет произвольные объемы памяти для учета (обязательно) ненулевых данных.
R ..

Вы можете получить его на один байт меньше main(){main(malloc(9));}, но для того, чтобы не переполнять стек, требуется оптимизация хвостовых вызовов, и gcc, похоже, не хочет делать это на main...
R ..

Если вы замените malloc (9) на calloc (9,9), тогда будет достаточно памяти, выделенной для 9 экземпляров 9-байтового блока (например, от 81 до 144 байтов, в зависимости от выравнивания. Однако, что более важно, calloc ( ) заполнит нулем блок памяти, вынуждая нижележащую ОС выделять ему хранилище.
CSM

5

Perl, 4 байта

do$0

Выполняет себя в текущем интерпретаторе. По окончании выполнение возвращается к вызывающему сценарию, для которого требуется стек вызовов.


Хороший и короткий, хотя он не тратит память быстро, как моя.
БенГольдберг

4

Ракетка, 13 байт

(let l()(l)1)

Я не совсем уверен, подпадает ли мой ответ под этот вопрос. Пожалуйста, дайте мне знать, если я должен удалить этот ответ.


Можете ли вы объяснить, как это работает?
tbodt

1
о, так что это определение lкак функция, которая выполняет рекурсию без вызова. Я бы сказал, что это имеет значение.
tbodt

@tbodt да ты прав на деньги
Винни

4

JavaScript 22 21 17 16 15 байт

for(a=0;;)a=[a]

Сохраните 4 байта, обернув список в другой список, как в ответе @Jonathan Allan's Jelly.

Сохранено 1 байт благодаря @ETHProductions

Альтернативное решение 15 байт (работает только с правильными оконечными вызовами)

f=a=>f([a]);f()

1
На вашем втором примере с ES6 не могли бы вы просто сделать f=_=>f();f()? 12 байт
битый

@bitten Я не уверен. Если он рассчитывает перебросить стек вызовов, то этот без правильных хвостовых вызовов будет подходящим вариантом. С TCO я не думаю, что будет какая-то утечка памяти, не так ли?
Lmis

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

1
ах, я вижу, я не был уверен, как у тебя течет память
укусил

1
Вы можете удалить a=0. Первая итерация приведет кa=[undefined]
Флорент

4

Рубин, 11 байт

loop{$*<<9}

Продолжает нажимать 9на $*массив, который изначально содержит аргументы командной строки для процесса Ruby.


4

05AB1E , 2 байта

[A

Попробуйте онлайн! Просто буду продолжать давить abcdefghijklmnopqrstuvwyxzна стек на вечность.

Все возможные 2-байтовые решения:

[  # Infinite loop.
 A # Push alphabet.
 0 # Push 0.
 1 # Push 1.
 2 # Push 2.
 3 # Push 3.
 4 # Push 4.
 5 # Push 5.
 6 # Push 6.
 7 # Push 7.
 8 # Push 8.
 9 # Push 9.
 T # Push 10.
 X # Push 1.
 Y # Push 2.
 ® # Push -1.
 ¶ # Push \n.
 º # Push len(stack) > 0, so 0 once then 1 for eternity.
 ð # Push a space.
 õ # Push an empty string.
 ¾ # Push 0.
 ¯ # Push [].
 M # Push -inf.
 ) # Wrap current stack in an array.

Очень тщательно! Приятно.
Тимотим

3

Python, 35 байт

def f(a=[]):a.append(a)
while 1:f()

a никогда не выпускается и просто становится больше, пока вы не нажмете MemoryError

Вы можете посмотреть исполнение на Python Tutor .


1
Вы можете сделать a+=a,?
Cyoce

Нет необходимости в функции, вот мой гольф этого
FlipTack

@ Flp.Tkc вопрос был изменен после того, как я написал этот ответ, я бы сделал то, что вы сделали (+ - пара символов), если бы он был в его текущем формате.
Noelkd

3

TI-BASIC, 8

:Lbl A
:While 1
:Goto A

(все 1-байтовые токены и две строки)

Это постоянно приводит к утечке памяти, потому что структурированный поток управления, такой как Whileожидаемое закрытие, Endи помещает что-то в стек (не в стек ОС, а в отдельный стек в кучной памяти), чтобы отслеживать это. Но здесь мы используем, Gotoчтобы выйти из цикла (так что no Endвыполняется, чтобы удалить объект из стека), Whileснова виден, объект снова перемещается и т. Д. Так что он просто продолжает нажимать их, пока вы не получитеERR:MEMORY

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.