フォーク爆弾なしでメモリリークを作成する[終了]


54

あなたの仕事は、メモリリークを作成することです。これは、コンピューターがなくなるまでメモリの負荷を使用するプログラムであり、コンピューターがなくなるのを防ぐためにスワッピングを行う必要があります。メモリを解放できる唯一の方法は、タスクマネージャーでプログラムを強制終了するか、taskkill /im yourprogram /f(Windowsの場合)などのコマンドライン強制終了を使用するか、コンピューターを再起動することです。単にアプリを閉じても、メモリを独占し続けることは妨げられません。

ルール:

  1. あらゆる種類のフォーク爆弾は禁止されています。つまり、悪名高いBashライン:(){ :|:&};:は禁止されています!

  2. アプリケーションはシングルスレッドのみである必要があります。これは、フォークボムルールを意味します。

  3. プログラムは他のプログラムを実行してはなりません。これはあなたがただのようなことができないことを意味しますrun(memoryfiller.exe)。これの唯一の例外は、OSまたは言語にバンドルされているプログラムであり、主にメモリを消費するように設計されていない(つまり、別の目的がある)プログラムです。これは、catおよびなどln -sが許可されていることを意味します。

  4. 好きなだけメモリを使用できます。より良い。

  5. コードは完全に説明する必要があります。

幸運を。これは人気コンテストなので、質問日から10日後に最も投票数の多いコードが勝ちます!


8
「それを閉じてもメモリを占有するはずです」-プログラムがシェル実行可能ファイルである場合(スクリプト言語インタープリターのほとんどのWindowsバージョンと同様)、ウィンドウを閉じるとプログラムが強制終了されます。
mniip 14年

54
これだけじゃないwhile(1)malloc(999);
ドアノブ

10
「それを閉じてもメモリを占有する」と「アプリケーションはシングルスレッドのみでなければならない」との互換性があるかどうかはわかりません。スレッドにメモリのチャンクがない場合、OSはそれを取り戻すことができますよね?
aebabis 14年

51
いくつかのタブを開いた状態でfirefox 26を実行し、フラッシュを30分実行します。コンピューターをひざまずかせます。
ブレーデンベスト14年

1
@mniip。それが挑戦の全体的なポイントです。難しい挑戦をすること。そしてドアノブ。違うものが欲しかった!;)
ジョージ14年

回答:


78

Win32 APIを使用すると、他のプロセスでメモリを割り当て、そのメモリをリモートで読み書きできます。このプログラムには1つのスレッドしかないため、システムで実行中の各プロセスを列挙し、割り当てが失敗するまで各プロセスに1MBのバッファーを繰り返し割り当てます。あるプロセスで終了すると、次のプロセスに進みます。割り当ては、呼び出しプログラムが終了しても解放されません-各ターゲットプロセスが終了した場合/終了した場合のみ。これにより、約10秒で2GBのWindows 7 VMがハングします。管理者として実行する必要があります。

コンパイルする: cl /MD leak.cpp /link psapi.lib

#include <windows.h>
#include <psapi.h>

typedef void (*ProcFunc)(DWORD pid);
#define ALLOC_SIZE 0x100000
LPVOID buf;

void ForEachProcess(ProcFunc f)
{
    DWORD aProcesses[1024], cbNeeded;

    if (!EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded))
        return;

    for (unsigned int i = 0; i < cbNeeded / sizeof(DWORD); i++)
        if (aProcesses[i] != 0)
            f(aProcesses[i]);
}

void RemoteLeak(DWORD pid)
{
    HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid );
    if (hProcess == NULL)
        return;

    for (;;)
    {
        LPVOID ptr = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, 
                                    MEM_COMMIT, PAGE_READWRITE);
        if (ptr == NULL)
            return;

        WriteProcessMemory(hProcess, ptr, buf, ALLOC_SIZE, NULL);
    }
}

int main(void)
{
    buf = malloc(ALLOC_SIZE);
    if (buf == NULL)
        return 0;

    memset(buf, 0xFF, ALLOC_SIZE);

    ForEachProcess(RemoteLeak);

    return 0;
}

9
Windowsは悪です。
tomsmeding

4
今夜シャットダウンする必要があります。これを試してみてください;)
ジョージ14年

1
「(通常のユーザ、管理者権限を使用していないとして動作している」 -これがわからない、あなたは、デフォルトでは、正規ユーザーのトークンに存在していないSeDebugPrivilegeを必要とする
rkosegi

@rkosegiありがとう、修正。
アンドリューメディコ14年

14
+1 これは元のクロージングを満たす唯一の答えであり、メモリ要件を維持する必要があるため、これまでのところ多くの賛成に値します。非常に創造的なソリューション:-)
ダニエル14年

72

Java

import java.util.concurrent.atomic.AtomicInteger;

public class Hydra {
  // Not actually necessary for the leak - keeps track of how many Hydras there are, so we know when they're all gone
  public static AtomicInteger count = new AtomicInteger(0);
  public Hydra() {
    count.incrementAndGet();
  }
  protected void finalize() {
    new Hydra();
    new Hydra();
    count.decrementAndGet();
  }

  public static void main(String[] args) throws InterruptedException {
    new Hydra();
    while (Hydra.count.get() > 0) {
      // Prevent leaks ;-)
      System.gc();
      System.runFinalization();
    } 
  }
}

説明

コードには参照が存在しないため(count安全に無視できる以外)、リークしないと想定するかもしれません。ただし、ファイナライザは2つの新しいHydrasを作成しますが、これらの参照も保持しませんが、ファイナライズされるまで待機します。これは、プログラムがガベージコレクション中にのみメモリをリークすることを意味します。したがって、System.gc()およびへの呼び出しはSystem.runFinalization()


7
@TimS。あなたの神は今どこにいるのか?!?
ランチャー14年

あるSystem.gc()System.runFinalization()必要?つまり、gcは時々ランダムに実行されますか、それともメモリをいっぱいにするか、gcを呼び出す必要がありますか?
ランチャー14年

4
典型的なプログラムでは、System.gc()およびSystem.runFinalization()必要ではないでしょう。ガベージコレクションは、メモリの負荷のために自然に発生します。ただし、このアプリケーションでは、ガベージコレクションの実行が開始されるまでメモリに負荷はかかりません。人工的にいくつかを導入することを考えました(たとえば、new Hydra()ループ内を移動することによって)が、これはより悪であると考えました。
James_pic 14年

1
うん、「@ german_guyのようなきちんとしたOSハックを除けば」意味がないように思えたので、「それを閉じてもメモリを独占する」という警告にはあまり注意を払わなかった。Javaは常にファイナライズスレッドを起動するため、おそらくJavaアプリケーションがルール2に従う方法はありません。
James_pic 14年

1
Unixシステムでは、SIGKILL(シグナル9)をブロックできないため、プログラムを停止不可能にすることはできません(まあ、それを無停止の待機状態にした場合を除いて...アクセスが機能する可能性があります
;

37

C

Cプログラミング言語を使用し、Linuxカーネル2.6.32-49-genericおよびlibc-2.11.1.soでテスト済み。

メモリを解放できる唯一の方法は、タスクマネージャでプログラムを強制終了するか、taskkill / im yourprogram / fを使用するか、PCを再起動することです。

これは、SIGKILLとSIGSTOPを除くすべてのシグナルをブロックすることにより実現されます。

閉じてもメモリを占有するはずです。

これは実際に私を混乱させます...それを殺すか閉じると、プロセスが終了し、オペレーティングシステムがプロセスによって割り当てられたメモリを要求できるようになります。しかし、私はそれを閉じることで、端末またはメモリリークプロセスを実行する他の親プロセスを閉じることを意味するかもしれないと考えるようになりました。私がそれを正しければ、親プロセスが終了したときにプロセスをデーモンに変える信号をブロックすることでこの問題を解決しました。そうすれば、プロセスが実行されている端末を閉じることができ、実行を継続してメモリリークを続行します。

あらゆる種類のフォーク爆弾は禁止されています。つまり、悪名高いbash:(){:|:&} ;:は禁止されています!

プロセスは分岐しません。

アプリケーションはシングルスレッドのみである必要があります。これは、フォークボムのルールを意味します

新しいスレッドは生成されません。

プログラムは他のプログラムを実行してはなりません。これは、単にrun(memoryfiller.exe)のようなことを実行できないことを意味します

新しいプロセスは生成されません。

好きなだけメモリを使用できます。より良い。

オペレーティングシステムが提供できる限り。

コードは完全に説明する必要があります。

ソースにコメントを追加しました。

最後にコードを示します。

#define _GNU_SOURCE

#include <stdio.h>
#include <signal.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdlib.h>


int main(int argc, char* argv[]) {

    /*
    set the real, effective and set user id to root,
    so that the process can adjust possible limits.
    if the process doesn't have the CAP_SETUID capability, terminate the process.
    */
    if (setresuid(0, 0, 0) == -1) {
        printf("Are you root?!\n");
        return 1;
    }

    /*
    block all signals except for kill and stop.
    this allows to terminate the parent process (most likely a terminal)
    that this process is running in and turn it into a daemon.
    additionally this makes it impossible to terminate the process
    in a normal way and therefore satisfies the requirement that closing
    it should still make it hog memory.
    */
    sigset_t mask;
    sigfillset(&mask);
    sigprocmask(SIG_SETMASK, &mask, NULL);

    /*
    allow the process to acquire a virtually unlimited amount of memory
    and queue a virtually unlimited amount of signals.
    this is to prevent an out of memory error due to a virtual limit for the root user,
    which would prevent the process from leaking any more memory
    and to prevent the process from getting killed due to too many queued
    signals that the process is blocking.
    */
    struct rlimit memory = { RLIM_INFINITY, RLIM_INFINITY },
                  signal = { RLIM_INFINITY, RLIM_INFINITY};
    setrlimit(RLIMIT_AS, &memory);
    setrlimit(RLIMIT_SIGPENDING, &signal);

    /*
    allocate a buffer big enough to store a file name into it
    that is generated from the process' pid.
    if the file can be opened (which should always be the case unless /proc is not mounted)
    the file will be opened and the string -17 followed by a new line written to it.
    this will cause the oom killer to ignore our process and only kill other,
    innocent processes when running out of memory.
    */
    char file_name[20];
    sprintf(file_name, "/proc/%u/oom_adj", getpid());

    FILE* oom_killer_file = fopen(file_name, "w");
    if (oom_killer_file) {
        fprintf(oom_killer_file, "-17\n");
        fclose(oom_killer_file);
    }

    /*
    get the size of virtual memory pages in bytes,
    so the process knows the size of chunks that have to be
    made dirty to force the kernel to map the virtual memory page into RAM.
    */
    long page_size = sysconf(_SC_PAGESIZE);

    // allocate a virtually infinite amount of memory by chunks of a page size.
    while(1) {
        // will overwrite any previous stored address in tmp, leaking that memory.
        char* tmp = (char*) malloc(page_size);
        if (tmp)
            // make the memory page dirty to force the kernel to map it into RAM.
            tmp[0] = 0;
    }

    return 0;
}

このプログラムを実行し続けた場合に何が起こるかに興味がある人のために:2GB RAMと4GBのスワップスペースがあるテストシステムでは、RAMをいっぱいにしてスワップするのに約10分かかりました。OOMキラーは作業を開始し、3分後にすべてのプロセスの種類が殺されました。マウス、キーボード、およびディスプレイでさえ、システムによってドロップされています。/var/log/kern.logは、強制終了されたプロセスを除き、有用な情報を表示しません。


ソースを編集して、oom killerがプロセスを無視し、無害なプロセスを強制終了してメモリを解放するようにしました。
フーバー14年

5
このプログラムを実行し続けた場合に何が起こるかに興味がある人のために:2GB RAMと4GBのスワップスペースがあるテストシステムでは、RAMをいっぱいにしてスワップするのに約10分かかりました。OOMキラーは作業を開始し、3分後にすべての種類のプロセスが強制終了されました。マウス、キーボード、およびディスプレイでさえ、システムによってドロップされています。/var/log/kern.logは、強制終了されたプロセスを除き、有用な情報を表示しません。
foob​​ar 14年

ハハ、それは素晴らしい!その説明を編集して回答に入れる必要があります。+1
ドアノブ

1
私はダウン投票しませんでしたが、コードをフォーマットできるので、コメントを読むために水平スクロールは必要ありません。
パエロエベルマン

2
1)入力/出力デバイスを処理するプロセスを強制終了し、2)ログから追跡するのが難しいプログラムを作成するための+1。これは口ひげを生やした悪のレベルです。
ケビン-復帰モニカ14年

29

ピュアバッシュ

フォークボムではない、私は約束する:

:(){ : $@$@;};: :

フォーク爆弾によく似ており、同様の再帰的手法を使用しますが、フォークは使用しません。 もちろん、これによりシェルがメモリ不足になりますので、このコマンドを貼り付ける前に新しいシェルを起動することをお勧めします。

  • という関数を定義する :
  • 関数は、$@(引数リスト)を2倍にして単純に再帰的に呼び出します
  • 関数定義の後、関数:は初期引数で呼び出されます:

出力:

$ bash
$ :(){ : $1$1;};: :
bash: xmalloc: ../bash/stringlib.c:135: cannot allocate 536870913 bytes (5368795136 bytes allocated)
$

この答えの以前の編集で私はやったがa=$(yes)、「プログラムは他のプログラムを実行してはならない」というルールに気づいたのでbash、coreutilsなどを呼び出さずに代わりにpureを使用する必要があります。


もう1つあります。

生産機械でこれを実行しないでください

:(){ : <(:);};:

繰り返しますが、これはフォークボムではありません。すべてが1つのスレッド内から実行されます。これは、Ubuntu VMを非常に便利にひざまずかせ、再起動以外の回復の余地がほとんどないようです。

古典的なフォーク爆弾のように、再帰関数:()が定義されています。ただし、それ自体への呼び出しは分岐しません。代わりに、プロセス置換で呼び出される1つの引数で自分自身を呼び出します。プロセス置換はファイル記述子を開くことで機能するため/dev/fd/n、プロセス(bash)メモリを消費するだけでなく、カーネルメモリも消費します。私のUbuntuマシンでは、これはウィンドウマネージャーを数秒後に操作不能にし、その直後にこの画面が表示されるという効果があります。

ここに画像の説明を入力してください

クリックするとOK、次の画面が表示されます。

ここに画像の説明を入力してください

これらのオプションはどれもあまり役に立たないようです-この時点で再起動が唯一の良いオプションのようです。


3
$ which yes->/usr/bin/yes
イズカタ14年

2
「メモリを解放できる唯一の方法は、タスクマネージャでプログラムを強制終了するか、taskkill / im yourprogram / fを使用するか、PCを再起動することです。それを閉じてもメモリが占​​有されるはずです。」>> SIGTERMを使用してbashを終了できるため、実行を停止するためにbashを終了する必要はありません。また、システムのメモリが不足すると実行が停止します。SIGTERMまたはメモリ不足によりbashが終了すると、メモリはオペレーティングシステムに戻されます。
フーバー14年

これは私にはうまくいきません...ある種...私は記憶が徐々に消えていくのを見ることができますが、これは非常にゆっくり起こり、ctrl + cを押すだけで殺すこともできます。現在1分間実行されており、約1GBを占有しています。私は非常に高速なマシンを持っています...しかし、それは問題ではないでしょう?
ステファノKalantzis

自分のコメントに返信する:コマンドは実際に約2分49秒後にbashを殺しました。私はもともと、この答えに基づいてインスタントになると思っていました。
ステファノスカランツィス

@StefanosKalantzisコメントありがとうございます。それはもう少し考えさせられ、さらに邪悪なシェルスニペットを見つけました-編集を参照してください。
デジタル外傷

24

XML

<!DOCTYPE boom [
<!ENTITY Z 'ka-boom!'><!ENTITY Y '&Z;&Z;'><!ENTITY X '&Y;&Y;'><!ENTITY W '&X;&X;'>
<!ENTITY V '&W;&W;'><!ENTITY U '&V;&V;'><!ENTITY T '&U;&U;'><!ENTITY S '&T;&T;'>
<!ENTITY R '&S;&S;'><!ENTITY Q '&R;&R;'><!ENTITY P '&Q;&Q;'><!ENTITY O '&P;&P;'>
<!ENTITY N '&O;&O;'><!ENTITY M '&N;&N;'><!ENTITY L '&M;&M;'><!ENTITY K '&L;&L;'>
<!ENTITY J '&K;&K;'><!ENTITY I '&J;&J;'><!ENTITY H '&I;&I;'><!ENTITY G '&H;&H;'>
<!ENTITY F '&G;&G;'><!ENTITY E '&F;&F;'><!ENTITY D '&E;&E;'><!ENTITY C '&D;&D;'>
<!ENTITY B '&C;&C;'><!ENTITY A '&B;&B;'><!ENTITY z '&A;&A;'><!ENTITY y '&z;&z;'>
<!ENTITY x '&y;&y;'><!ENTITY w '&x;&x;'><!ENTITY v '&w;&w;'><!ENTITY u '&v;&v;'>
<!ENTITY t '&u;&u;'><!ENTITY s '&t;&t;'><!ENTITY r '&s;&s;'><!ENTITY q '&r;&r;'>
<!ENTITY p '&q;&q;'><!ENTITY o '&p;&p;'><!ENTITY n '&o;&o;'><!ENTITY m '&n;&n;'>
<!ENTITY l '&m;&m;'><!ENTITY k '&l;&l;'><!ENTITY j '&k;&k;'><!ENTITY i '&j;&j;'>
<!ENTITY h '&i;&i;'><!ENTITY g '&h;&h;'><!ENTITY f '&g;&g;'><!ENTITY e '&f;&f;'>
<!ENTITY d '&e;&e;'><!ENTITY c '&d;&d;'><!ENTITY b '&c;&c;'><!ENTITY a '&b;&b;'>
]>
<boom a="&a;"/>

次に、エンティティ参照ループ/再帰検出を行わないXMLパーサーにドキュメントを渡します。たとえば、xpathperl に含まれています:

xpath boom.xml /

使い方:

  1. パーサーが遭遇する <boom a="&a;">
  2. パーサは拡大"&a;""&b;&b;"
  3. パーサーは、一方を展開"&b;"します"&c;&c;"(戻ると、もう一方を展開します"&b;"
  4. パーサーは、"&c;"等のいずれかを展開します...

完全に展開できる場合、「ka-boom!」の2 ^ 52の展開があります。1文字あたり2バイトと仮定すると、64 PiBを使用しようとします。拡張は「ka-boom!」一度に、したがって、通常、それが一番上のすべてのメモリを使い果たすのを見ることができます。

これはさまざまな名前で行われますが、概要はこちらをご覧ください:http : //projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion



@ColeJohnsonそうです!私はWASC脅威分類プロジェクトに貢献したため、WikipediaではなくWASCを指し示す義務がありました。:)
ɲeuroburɳ

22

C ++

int main()
{
    for(;;)int *a=new int;
}

このコードは予想外でした!タスクマネージャーが開いているときにコンピューターがハングし、1秒で890 Mbのメモリが必要であることがわかりました。私は文を追加多分それは、このコードの詳細をみるvariable.Toにメモリを与え続けている、これがどのように動作するか分からないdelete a;と(何のハング)をテストしていない間、すべてのものは大丈夫だったので、私は、メモリのチャンクがあると思いますに与えられ(に起因するnew int)、次に(に起因するdelete a)下の新しいコードの空きスペースに戻されます。

int main()
{
    for(;;)
    {
         int *a=new int;
         delete a;
    }
}  

したがって、この世界のRAMはこのコードを処理できないと私は結論付けます!!!

編集しかし、多くのプロセッサは、たとえばintel core 2 duoこのコードを処理することはできませんが、
intel core i-seriesできます(私のために働いた...)

質問への答えは1番目のコードであり、2番目は説明用です。


9
コンパイラはnew int、ポインタを上書きしてもまだ使用すると考えているため、ガベージコレクションは呼び出されず、太った子供がスキットルズを食べるよりも速くメモリを使い果たします
David Wilkins

37
@DavidWilkins:...これはC ++であり、C ++にはガベージコレクタがありません。
Phoshi

32
このコードがリークすることが予想外の場合、C ++をよりよく理解するまで使用しないでください。
14年

1
@svickしかし、それはまた、暗闇の中でダーツを打つようなものではありません!私はこれが仕事の質問が望んでいるという考えをいくつか持っていました。
ムクルクマール14

15
@svick「C ++を使用するべきではない」場合、彼はどのように「もっとよく学ぶ」べきなのでしょうか?
ケビン14年

16

BrainFuck

+[>+]

説明:

ループに入ると、セルは1に増加します。最後のセルが正である限り、次のセルに移動して1に増加します。

通常、BrainFuckインタープリターには、テープ上のセルの数に厳しい制限があるという欠陥がありますが、一部のインタープリターはセルを動的に追加します。これらは、消費しなくなるまでメモリを消費し続けます。

beefこのようなインタープリターの1つであり、Ubuntu Software Centerで入手できます。未使用のマシンでの現在の実行は29時間前に開始され、その間に1GBのRAMを消費しました。これが出力ですtop

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 1030m 984m 2536 R 100,1 12,4   1750:52 beef

4GBのキャッシュと6GBのスワップがあるため、この回答を約12日間でどのように更新したかを推測します。

更新03.24 17:11

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 1868m 1,8g 2456 R  99,9 22,9   6008:18 beef    

更新03.31 00:20

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 2924m 2,8g 2052 R 100,0 36,1  15019:46 beef   

そのため、10日間実行されています。何か面白いことが起こる前に、少なくとも10日間は実行されているようです。


素敵で短い。
nrubin29 14年

15

CおよびPOSIX

ここで私は、移植性の高いソリューションを目指しています。問題は、純粋なCには、プログラムを閉じた後もメモリを割り当てたままにする必要があることをオペレーティングシステムに伝える方法がないように見えることです。したがって、POSIXを使用できるようにします。ほとんどのOSは、Windows、Linux、およびMacOS Xを含むPOSIX互換性を主張しています。ただし、Ubuntu 12.04 32ビットでしかテストしていません。スーパーユーザーのアクセス許可は必要ありません。

このソリューションは、本質的に従来のwhile(1){malloc(1);}ソリューションです。ただし、mallocの代わりに、POSIX共有メモリ関数を使用します。共有メモリ識別子を各割り当てに割り当てるため、プロセスが終了するとメモリにアクセスできます。したがって、カーネルはメモリを解放できません。

#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>

#define SHMSZ (2*1024*1024) /*Ubuntu rejects shared allocations larger than about 2MiB*/

main() {
  int shmid;
  key_t key = 0xF111; /* Lets use `Fill' as our first ID.*/
  char *shm;

  while(1) { /* Like malloc, but using shared memory */
    if ((shmid = shmget(key, SHMSZ, IPC_CREAT|0666)) < 0){return 1;}/*Get shared memory*/
    if ((shm = shmat(shmid, NULL, 0)) == (void *) -1) { return 1; } /*Attach it        */
    memset(shm,0,SHMSZ);                                            /*Fill it up       */
    key++                                                           /*On to the next ID*/
  }
}

最高で最も素晴らしいCがIMOに答えます。+1
syb0rg 14年

1
良いですね。最初に思いついた解決策はAndrew Medicoでしたが、それはLinuxでは不可能であり、Windowsプログラミングが好きではないため、共有メモリを介してリークしたかったのですが、POSIX関数名を思い出せませんでした。それらの私を思い出してくれてありがとうは;)私が見つけたすべては...プロセスの終了時に、マッピングされていない場合のみのmmapものだった
foob​​arの

14

C#

ハンドラーがスコープ外になる前にイベントのサブスクライブを忘れると、.NETはOutOfMemoryExceptionをスローするまでメモリをリークします。

using System;

class A
{
    public event Action Event;
}

class B
{
    public void Handler() { }
}

class Program
{
    static void Main()
    {
        A a = new A();

        while( true )
            a.Event += new B().Handler;
    }
}

説明whileループ内で、新しいオブジェクトを作成し、フレームワークにより多くのメモリを割り当てますがB、インスタンスクラスを別のクラスのイベントに割り当てることにより、スコープ外になったときに新しいインスタンスが解放されないようにします。その結果、の新しいインスタンスはBコードから到達できなくなりますが、参照はまだ存在します。つまり、GCはaスコープ外になるまで解放しません。

静的イベントにも同じ落とし穴があります。スコープから外れることはないため、最初にイベントの購読を解除しない限り、プロセスが終了したときにのみクリーンアップされます。参照は常に保存してください!

using System;

class Program
{
    static event Action Event;

    static void Main()
    {
        while( true )
            Event += new Action( delegate{ } );
    }
}

上記は同じ考え方で動作しwhileます。ループがスコープ外に出るとハンドラーが到達不能になり、イベントからサブスクライブを解除できなくなります。つまり、プログラムが終了するまでメモリがそこに留まります。静的イベントは、インスタンスイベントよりもほぼ間違いなく危険です。これは、静的イベントがスコープの外に出ないことを保証できるためです。

編集:参照を追加すると同時に、その参照を解放する方法がないことを保証する限り、基本的に他のオブジェクトでも同じことができます。

静的オブジェクトと配列を使用する例を次に示します。

using System;
using System.Collections.Generic;

static class Leak
{
    private static List<decimal[]> Junk;

    static Leak()
    {
        Junk = new List<decimal[]>();
    }

    public static void Add( uint size )
    {
        decimal[] arr = new decimal[size];
        Junk.Add( arr );
    }
}

class Program
{
    static void Main()
    {
        while( true )
            Leak.Add( 1 );
    }
}

配列はリストに追加され続けますが、コードを変更せずにリストをクリアする方法はありません。これは、クローズドソースアプリケーションでは不可能です。渡される数を増やすと、Leak.Addリークが速くなります。十分に高く設定すると、ただちにOverflowExceptionがスローされます。


10

bash(外部ユーティリティなし)

ここにはフォーク爆弾はありません。

警告:それはあなたのシェルを殺すかもしれません。

整数がどのように見えるかを忘れ続けるため、参照用に整数の配列を作成しようとしています。

while :; do _+=( $((++__)) ); done

結果:

xmalloc: expr.c:264: cannot allocate 88 bytes (268384240 bytes allocated)

2
+1の「整数がどのように見えるかを忘れがちだから」:)
デビッドコンラッド

8

J(7)

警告:試したときにシステムがフリーズしました(qtターミナルのWindows 8、J 8.01)。

2#^:_[_
  • 2# 各要素を複製して引数の長さを2倍にします。
  • ^:_ 指定された関数の不動点を見つけます(ただし、不変なので、無限にループします)。
  • [__引数としてそれを呼び出します。

8

ハスケル(グラハムの数)

とても簡単です。これはグラハムの数を計算します

ここの他の例とは異なり、永久に実行されることはありません...多くのCPUを使用しますが、理論的には終了する可能性があります。番号を保存するという事実がなかったら...

観測可能な宇宙は、各数字が1つのPlanckボリュームを占めると仮定して、グラハムの数の通常のデジタル表現を含めるには小さすぎます。

(ウィキペディアによると)

import Data.Sequence
import Data.Foldable

(↑) a 1 b = a ^ b
(↑) a _ 0 = 1
(↑) a i b = a ↑ (i-1) $ a ↑ i $ b-1

graham = last $ toList $ iterateN 64 (\i -> 3 ↑ i $ 3) 4
main = print graham

そのため、メモリは(ますます増加する)巨大なメモリInteger(Haskellの整数は任意のサイズ)によって使用されるという考え方です。

テストする場合は、スタックサイズを増やすか、内部にロードする必要がありますghci


2
整数のHaskell標準に準拠していない、ダムユニバース。なぜそれは任意のサイズをサポートできないのですか?
PyRulez 14

6

@cominternに触発されました。

/ dev / nullを置き換えます。スニーキーモードを有効にします。カーネルヘッダー、スーパーユーザーモード、および動作中のコンパイラが必要です。

# make
# rm /dev/null
# insmod devnull.ko
# chmod go+rw /dev/null

楽しんで。

メイクファイル:

MODULE := devnull
KVERS  ?= $(shell uname -r)
KDIR   ?= /lib/modules/$(KVERS)/build
KMAKE := make -C $(KDIR) M=$(PWD)

obj-m += $(MODULE).o

all:
    $(KMAKE) modules

install:
    $(KMAKE) modules_install

clean:
    $(KMAKE) clean

ソースコード:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/version.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>

#define DEVICE_NAME "null"
#define MAJOR_NUMBER 0

MODULE_LICENSE("GPL");
MODULE_AUTHOR("nola <florian@n0la.org>");
MODULE_DESCRIPTION("/dev/null - memory leak style");
MODULE_VERSION("0.1");
MODULE_SUPPORTED_DEVICE("null");

static struct class *class_null;
static int major = 0;

static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
static loff_t device_llseek(struct file *, loff_t, int);

static struct file_operations fops = {
    .owner = THIS_MODULE,
    .llseek = &device_llseek,
    .read = &device_read,
    .write = &device_write,
    .open = &device_open,
    .release = &device_release
};

static int __init mod_init(void)
{
    struct device *dev_null;

    if ((major = register_chrdev(MAJOR_NUMBER, DEVICE_NAME, &fops)) < 0) {
        return major;
    }

    /* create /dev/null
     * We use udev to make the file.
     */
    class_null = class_create(THIS_MODULE, DEVICE_NAME);
    if (IS_ERR(class_null)) {
        unregister_chrdev(major, DEVICE_NAME);
        return -EIO;
    }

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
    dev_null = device_create(class_null, NULL, MKDEV(major, 0),
                             NULL, "%s", DEVICE_NAME
        );
#else
    dev_null = device_create(class_null, NULL, MKDEV(major, 0),
                             "%s", DEVICE_NAME
        );
#endif
    if (IS_ERR(dev_null)) {
        class_destroy(class_null);
        unregister_chrdev(major, DEVICE_NAME);
        return -EIO;
    }

    return 0;
}

static void __exit mod_exit(void)
{
    device_destroy(class_null, MKDEV(major, 0));
    class_unregister(class_null);
    class_destroy(class_null);
    unregister_chrdev(major, DEVICE_NAME);
}

static int device_open(struct inode *inode, struct file *file)
{
    file->f_pos = 0x00;

    try_module_get(THIS_MODULE);
    return 0;
}

static int device_release(struct inode *inode, struct file *file)
{
    /* decrement usage count: Not. Uncomment the line for less fun. */
    /* module_put(THIS_MODULE); */
    return 0;
}

static loff_t device_llseek(struct file *filep, loff_t offs, int mode)
{
    loff_t newpos;

    switch (mode) {
    case 2:
    case 0:
        newpos = offs;
        break;

    case 1:
        newpos = filep->f_pos + offs;
        break;

    default:
        return -EINVAL;
    }

    if (newpos < 0) {
        return -EINVAL;
    }

    filep->f_pos = newpos;

    return newpos;
}

static ssize_t device_read(struct file *filep, char *dst, size_t len,
                           loff_t *off)
{
    char *buf = NULL;

    if (dst == NULL || len == 0) {
        return -EINVAL;
    }

    buf = kmalloc(sizeof(char) * len, GFP_KERNEL);
    if (buf == NULL) {
        return -EINVAL;
    }

    /* Do how a /dev/null does.
     */
    memset(dst, 0, len);

    *off += len;
    return len;
}

static ssize_t device_write(struct file *filep, const char *src, size_t len,
                            loff_t *off)
{
    char *buf = NULL;

    buf = kmalloc(sizeof(char) * len, GFP_KERNEL);
    if (buf == NULL) {
        return -EINVAL;
    }

    *off += len;
    return len;
}

module_init(mod_init);
module_exit(mod_exit);

これにより、強制的に再起動する場合があります!

削除するには:

# rmmod -f devnull # or a reboot
# rm -rf /dev/null
# mknod /dev/null c 1 3
# chmod go+rw /dev/null

6

ルビー

誰もがsum(1 / n ^ 2)= pi ^ 2/6であることを知っています

したがって、近似関数を定義できます。

pi_approx = lambda {|i|
Math.sqrt( 
  6*( 
    (1...Float::INFINITY).map{|n| n.to_f**(-2)}.take(i).reduce(:+)
    )
  )
}

p pi_approx.(100_000)

もちろん、(1..infinity)はワイルドになります。

ただし、lazyを使用するとこの作業が可能になることに注意してください;)

pi_approx = lambda {|i|
Math.sqrt( 
  6*( 
    (1...Float::INFINITY).lazy.map{|n| n.to_f**(-2)}.take(i).reduce(:+)
    )
  )
}

p pi_approx.(100_000)
#=> 3.141583104326456

5

C- 28 25文字(フルプログラム)

実行しないでください。実行すると、システムがすぐにフリーズします。

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

mallocの呼び出しは、9バイトのメモリを予約し、オペレーティングシステムに新しいメモリページを定期的に要求します。返されたアドレスへのポインタが保存されていないため、mallocによって割り当てられたメモリはすぐにリークされます。システムがメモリ(RAMとスワップ領域)を使い果たすか、プロセスのメモリ制限に達すると、プログラムはwhileループを抜けて終了します。


2
それほど長くはない-合理的に最新のシステムには、プロセスを開始して強制終了するOOMキラーが必要です。少なくともUbuntu 12.04ではできます。
デジタル外傷14年

1
さて、このコードを試している間にUbuntu 13.10をクラッシュさせました...
Mathieu Rodic 14年

@DigitalTraumaたとえば、FreeBSDにはOOMKがありますか?
ルスラン14年

1
main(){while(malloc(9));}さらに3文字を節約し、ほとんど瞬時に記憶を満たします。
gmatht

@gmatht:提案をありがとう!私は答えを編集しました...しかし、私はすべてのループでブロックのサイズを増やすというアイデアが好きでした。
マチューロディック14年

4

VBScript

do
    Set d1 = createobject("Scripting.Dictionary")
    d1.add true, d1
    Set d1 = Nothing
loop

私たちは自分自身を指す辞書を作成しています。次に、辞書をNothingに設定することにより、辞書を破棄すると考えます。ただし、辞書は有効な(循環)参照を持っているため、メモリ内にまだ存在しています。

ループだけでなく、メモリの占有により、プログラムがハングします。プログラムのシャットダウン後、メモリはまだ使用中です。システムは、再起動することによってのみ復元できます。


えっ、本当に?VBScriptは内部でVB.NETを使用するだけではありませんか?単純な参照カウントの実装を除き、循環参照は通常、ガベージコレクターの問題ではありません。プログラムを終了すると、ヒープ全体が解放されます。
デビッドコンラッド14年

@DavidConradそう思いますが、これを調査してこのタイプのスクリプトを実行するたびにマシンを再起動する必要がありました。
AutomatedChaos 14年

1
VBScriptはVB.Netよりもかなり前のバージョンです。VB.Netのコマンドラインバージョンではありません。これは、レガシーVisual Basicの解釈されたサブセットです。
クリスJ 14年

おかげで、あなたの両方。VBScriptとVB.NETの関係が何であるかを知りませんでした。
デビッドコンラッド14年

4

はい&tmpfs

Ubuntuで無料で提供される新しいプログラムを作成する理由は何ですか?

yes > /run/user/$UID/large_file_on_my_ramdisk

ご存知かもしれませんが、すでに推測しているように、UbuntuはRAMディスクの一種であるtmpfsとして/ run / user /をデフォルトでマウントします。

閉める必要さえありません。丁寧に自分自身を閉じ、割り当てられたメモリの素敵な部分を残します。私yesは、他のものを呼び出さないシングルスレッド、シングルプロセスのプログラムであると推測します(既存のRAMディスクへの書き込みも、選択した言語に簡単に移植できます)。

マイナーなバグがあります。Ubuntuは、ユーザーが書き込み可能なtmpfs / run / 1000をデフォルトで100 MBに制限しているため、すぐにマシンでスワップデス機能がサポートされない場合があります。しかし、次の簡単な回避策でマシン上でこれを修正することができました。

sudo mount -o remount,size=10G tmpfs /run/user/

/run/userディレクトリがまったくありません。どのバージョンのUbuntuを使用しており、これのために何をインストールしましたか?
ルスラン14年

Ubuntu Trusty Tahr(14.04)。特別なインストールは必要ありません。
gmatht

tmpfsファイルシステムがマウントされているかどうかを確認するには、でリストしますdf -t tmpfs。私のUbuntuシステムには、素敵な大あり/run/shm...利用可能
トビースパイツ

4

バッシュ

警告:次のコードにより、コンピューターが起動できなくなります。

printf "\\xe8\\xfd\\xff" | dd of=/dev/sda
reboot

警告:上記のコードにより、コンピューターが起動できなくなります。

/ dev / sdaをブートドライブに置き換えます。これにより、ブートセクタの先頭にE8 FD FFが書き込まれます。ブート時に、BIOSはブートセクタをメモリに読み込んで実行します。これらのオペコードは、このアセンブリと同等です:

label:
  call label

これは無限再帰であり、最終的にスタックオーバーフローを引き起こします。


アセンブリの例ではjmpcall
19:39

呼び出しは、retのためにスタック上に戻りアドレスを残します。ジャンプはスタックオーバーフローを引き起こしません。
ジェリージェレミア

3

ハスケル

main=print $ sum [0..]

これは、カウント数を合計しようとします。Haskellは部分和を評価しますが、無限の加算ステートメントになります。最適化フラグを指定してコンパイラを実行すると、動作しない場合があります。


3

バッシュ

メモリを消費するように特に設計されていないユーティリティを使用できるため、メモリを解放するユーティリティに焦点を当てますswapon。これは、カーネルがディスクに書き込むことでメモリを解放できるようにするために使用されます。

このスクリプトは、2つの最適化を実行します。(1)tmpfs(RAMディスクの一種)としてtmpをマウントして/ tmpを高速化する、(2)スワップファイルを作成してメモリを解放します。これらはそれぞれ合理的ですが、不注意なユーザーが両方を実行すると、スワップサイクルが設定されます。OSがページをスワップアウトしようとすると、tmpfsに書き込みます。これにより、tmpfsはより多くのメモリを使用します。これにより、メモリの負荷が高まり、より多くのページがスワップアウトされます。これは私のVMで数分かかる場合がありますが、システムを使用してシステムが穴を掘るのを見るのに十分な時間がかかりますtop

プログラム自体はほとんどメモリを割り当てないため、プログラムを閉じてもほとんど違いはありません。実際swapoff、スワップファイルの前にtmpfsをアンマウントしてメモリを解放することはできないため、メモリを解放することは簡単ではありません。また、メモリを解放するまで実行するのは困難です。

この答えは、それらを理解せずにネットからクールなトリックを適用する目隠しに対する警告物語と考えることができます。

sudo mount -t tmpfs -o size=9999G tmpfs /tmp # Use tmpfs to make /tmp faster
truncate -s 4096G /tmp/swap                  # Now make a giant swap file to free up memory 
sudo losetup /dev/loop4 /tmp/swap            # Use a loopback so we can mount the sparse file
sudo mkswap /dev/loop4
sudo swapon /dev/loop4
#The following line would cause a quick swap death, but isn't needed.
#dd if=/dev/zero of=/tmp/zero bs=1          # Zero the tmp dir so the VM can free more memory

2

Perl

sub _ {
  my($f,$b);
  $f=\$b;$b=\$f;
}
while(1) { _;}

循環参照を使用します。変数の参照カウントが0に達することは決してなく、参照がガベージコレクションされることもありません。

我慢する必要があるかもしれませんが、システムを停止させることが保証されています。ディスクの回転が速くなり、煙が見える場合があります。


2

PHP(Linuxのみ):

このコードはテストされていません。PHPを実行しているLinuxコンピューターがないためです。

しかし、これは私の概念実証です:

ignore_user_abort(true);
ini_set('memory_limit',-1);
ini_set('max_execution_time',0);
/*
    sets php to ignore if the script was canceled in the browser
    (like clicking cancel or closing the browser)
    and takes away the memory limit,
    as well as the maximum execution time.
*/

function dont_let_it_stop(){shell_exec('php '.__FILE__.' &');}
//this function calls the file itself.

register_shutdown_function('dont_let_it_stop');
//this function will register the function declared above to be used when the script is being terminated

function get_info($f='current')
{
    return str_replace(' kB','',end(explode(':',trim($f(explode(PHP_EOL,file_get_contents('/proc/meminfo')))))))*1024
}
/*
    this function fetches the infos
    'current' fetches the max memory
    'next' fetches the actual used memory
*/

$max=get_info();//maximum memory
$current=get_info('next');//current memory

$imgs=array(imagecreatetruecolor(1e4,1e4));
$color=imagecolorallocatealpha($imgs[$i=0],128,128,128,126);
imagefill($imgs[$i],0,0,$color);
/*
    this creates an array and inserts one image (10000x10000 pixels),
    filling it then with a solid transparent color
*/

$total-=get_info('next');//calculates the space an image takes

while($max-get_info('next')>$total*2)//while the free memory is higher than the memory of 2 images, fill the array
{
    $imgs[$i++]=imagecreatetruecolor(1e4,1e4);
    $color=imagecolorallocatealpha($imgs[$i-1],128,128,128,126);
    imagefill($imgs[$i-1],0,0,$color);
}

//this is just to keep the images in memory, so the script doesn't end
while(1)sleep(60);

これにより、メモリが巨大なRGBA画像(10000x10000ピクセル)でいっぱいになります。

この赤ちゃんをシャットダウンする唯一の方法は、電源を切ることです。

コードはすべてコメント化されています。

改善点、疑い、バグなど、下のコメントボックスを使用してください。


Linuxにアクセスできる人は誰でもテストしてくれるでしょうか?ありがとう:)
ジョージ14年

Linuxがありますが、どのように機能するのかわかりません。私は最初の答えにプリントスクリーンを提供しましたが、それはpuppy linuxの本当に古いバージョンです。Ubuntuは遅すぎてphpを実行できません。たぶん後でAndroidでテストします。
イスマエルミゲル14年

1
別のプログラムを呼び出さないことに関する論点に失敗しました
Einacio 14年

別のプログラムを呼び出しているのではなく、同じファイルのファイルを開始した同じプログラムを呼び出しています。
イスマエルミゲル14年

2

パイソン-56

class x:
 def __setattr__(self,*args):self.y=0
x().y=0

クラスを作成し、属性を設定するメソッドを定義し、その中に属性を設定し、属性を設定しようとする初期インスタンスを作成します。

単純な再帰関数(def f(x):f(x))は少し想像力に欠けるように見えたので、実際に関数を呼び出さないことにしました。

メモリ管理は再帰の深さをキャッチするかもしれませんが、実際には実装に依存します。

これがフォークボムなら、教えてください。


4
これにより、メモリが枯渇することはなく、a:のみとなりますRuntimeError: maximum recursion depth exceeded while calling a Python objectsys.setrecursionlimitセグメンテーションフォールトでクラッシュする前に、メモリがほとんどない最大再帰制限を設定することさえ使用されます。
バクリウ14年

@Bakuriu私が言ったように、それは実際に実装に依存します(C(++)に変換してコンパイルするPythonの実装があります、例えばShedskin、Nuitka)。
cjfaure 14年

2
次に、コードを記述している特定の実装について説明します。構文だけが重要であり、したがって実装が重要ではない課題と、言語の実装方法に完全に依存する課題には違いがあります。
バクリウ14年

2

Perl

シンプルなものですが、ゴルフをしたい気分でした。

{$x=[$x];redo}

2回の反復後、を$x含む配列への参照を含む配列への参照が含まれundefます。

メモリ使用量は時間的に直線的で、小さな割り当てがありますが、Ubuntu Linuxシステムでウィンドウマネージャーを著しく遅くするのに数秒しかかかりませんでした。30分後、OOMキラーがそれを処理しました。


2

ECMAScript 6:

z=z=>{while(1)z()};_=i=>(i+=1,i-=1,i++,i--,--i,++i,i<<=2,i>>=2,i+=0|Math.round(1+Math.random())&1|0,z(x=>setInterval(x=>z(x=>new Worker('data:text/javascript,'+_.toSource()),5))));setInterval(x=>z(x=>_(...Array(9e3).map((x,z)=>z*3/2*2/4*4e2>>2<<2))),5)

ゴルフをしていない:

function forever(code) {
    // Loop forever
    var counter = 0;

    while (counter++ < 10) setInterval(code, 5);
};

function main(counter) {
    // Do some work.
    counter += 1; counter -= 1;

    counter++; counter--;
    --counter; ++counter;

    counter <<= 2;
    counter >>= 2;

    counter += 0 | Math.round(1 + Math.random()) & 1 | 0;

    forever(() => {
        setInterval(() => {
            forever(() => new Worker('data:text/javascript,' + main.toString()));
        }, 5);
    });
};

setInterval(() => {
    forever(() => {
        main(...Array(9e3).map((currentValue, index) => index * 3 / 2 * 2 / 4 * 4e2 >> 2 << 2));
    });
}, 5);

注: Timerの一部として定義されているを使用しますsetTimeout。これはHTML Living Standardです。

Mozilla Firefoxで試してみてください(開発者コンソールに貼り付けることができます)。Firefoxはますます多くのメモリを消費し続け100%、シングルコアマシンでCPU を使用します(私のような4コアマシンで25%は、CPUを使用します)。また、停止できないという追加の利点もあります。タスクマネージャーを開くことができれば、Firefoxを終了できます。


1
コアの100%を使用します。クアッドコアプロセッサでは、CPU使用率が25%になります。
イヴァンペレス14年

@Electrosaはい、あなたは絶対に正しいです。回答を更新しました。
歯ブラシ14年

これはコードに関するゴルフの質問ではありません。コードを読みやすくしてください。
パウロEbermann

@PaŭloEbermannOK。私は無料版を投稿しました。
歯ブラシ

1

バッシュ

空のファイルを作成するこのテキストファイルでtest
置き換え/dev/null/ます

$ sudo mv test /dev/null

これは、@ Cominternの回答と同様の方法で機能します。へのすべての出力が/dev/nullこのテキストファイルに追加され、時間が経つとシステムがクラッシュします。


1
巨大なファイルはシステムをクラッシュさせません。また、ディスクの平均サイズを500ギガバイトと仮定すると、ファイルがディスクをいっぱいに近づけるまでに長い時間がかかります。
w4etwetewtwet 14年

1
/devがあるシステムでは、システムdevtmpfsがいっぱいになり、システムを妨害する可能性があります。これがこの答えの意図だと思います。
トビー・スペイト

1

Bash:7文字

これは最も単純なbashソリューションでなければなりません。フォークもカンニングもありません。

x=`yes`

これをルートとして実行しないことをお勧めします。


追記:ctrl-cで途中で終了してunsetから変数で終了しても、シェルが強制終了されるまでメモリは割り当てられたままです。で虐殺を見ることができtopます。
暴動14年

bash 4.2.45(1)を使用した独自のテストでunset xは、メモリが解放されることが示されています。pdkshもメモリを解放しますが、ksh93はメモリの解放に失敗しexit、ksh93でコアをダンプします。
カーニグ14年

私(bash 4.3.11(1))の場合、親シェルの最上部にある常駐メモリディスプレイyesは、殺されるまで着実に上昇しunsetます。しかし、これは大規模なメモリシステム上にあり、数ギガバイトの変数を使用しても問題はないようです(最終的にシェルを終了するまで)。
暴動14年

0

C

main()
{
    void * buffer;
    while (1)
        buffer = malloc(4096);
}

まあそれはページごとにメモリを取り、最終的にはメモリが残っていません。


ページが4 KBであることはどれくらい普遍的ですか?
ピーターモーテンセン14年

@Peter 4Kは多くの場合サイズですが、本当に普遍的かどうかはわかりませんが、ページサイズは特定の質問と関係がありません。
ST3

1
@ ST3:メモリページをダーティにする必要があります。最新のオペレーティングシステムのほとんどは、仮想メモリを使用し、メモリを割り当てるときに仮想メモリテーブルにレコードを作成します。メモリページに1バイトを書き込むと、オペレーティングシステムは既に仮想メモリページを物理メモリにマップします。
フーバー14年


0

ルビー

a=[];loop{a<<a}

自己参照をそれ自体に無限に追加します(再帰的!)。

誰かが私のRubyサンドボックスを壊したときに、この小さな宝石について知りました。:D

再帰的な側面のデモ:

[1] pry(main)> a=[]; a<<a; a
=> [[...]]
[2] pry(main)> 

0

C ++ 79

void f(char *p,int i){p=new char[i];f(p,++i);}
int main(){char c='a';f(&c,1);}

非ゴルフ

void leak(char *p,int i)
{
    p=new char[i];
    leak(p,++i);
}

int main()
{
    char c='a';
    f(&c,1);
}

mainからの呼び出しを含めるようにエントリを修正しました。


これは人気コンテストです。プログラムが機能する場合は、メインとヘッダーを保持します。大丈夫だよ。また、非ゴルフバージョンを投稿できますか?ありがとう:)
ジョージ14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.