可能な限り少ないバイトでメモリをリーク


79

あなたの仕事は、可能な限り少ないバイトで少なくとも1バイトのメモリをリークするコードを書くことです。割り当てられたメモリだけでなくメモリもリークする必要があります

リークメモリとは、プログラムが割り当てるメモリですが、メモリの割り当てを適切に解除する前にアクセスする機能を失います。ほとんどの高レベル言語では、このメモリをヒープに割り当てる必要があります。

C ++の例は、次のプログラムです。

int main(){new int;}

これにより new intそれへのポインタなしでヒープを作成します。このメモリは、アクセスする方法がないため、すぐにリークされます。

Valgrindからのリークの概要は次のようになります。

LEAK SUMMARY:
   definitely lost: 4 bytes in 1 blocks
   indirectly lost: 0 bytes in 0 blocks
     possibly lost: 0 bytes in 0 blocks
   still reachable: 0 bytes in 0 blocks
        suppressed: 0 bytes in 0 blocks

多くの言語にはメモリデバッガー(Valgrindなど)があります。そのようなデバッガーからの出力を含めて、メモリリークを確認する必要があります。

目標は、ソースのバイト数を最小限にすることです。


2
おそらくあなたは、漏れた量の異なる範囲を持っているし、あなたがあなたのバイト数のX%を失うことに漏れるどのくらいに応じて、可能性
クリストファー・

11
@ChristopherPeart 1つはチャレンジのボーナスのファンではありませんが、2つはすでに示したように、無制限のメモリをリークすることは非常に簡単です。
小麦ウィザード

1
関連。ただし、その質問に対するほとんどの回答は、実際にメモリをリークするのではなく、メモリ内で無限に到達可能な構造を形成するため、重複ではありません。

2
アイデアは何ですか?メモリを解放できないことは?これには、ガベージコレクションされた言語のネイティブ実行またはバグの悪用が必要だと思います。
アコスタディノフ

7
私は...ゴルフのために設計された言語はこの1つに無残に失敗どのように見る
Kh40tiK

回答:


89

Perl(5.22.2)、0バイト

オンラインでお試しください!

空のプログラムでメモリをリークする言語があることは知っていました。私はそれがエソランであると思っていましたが、それperlはどのプログラムでもメモリをリークすることが判明しました。(とにかく終了することがわかっている場合にメモリを解放すると時間が無駄になるため、これは意図的であると想定しています。そのため、最近の一般的な推奨事項は、プログラムの出口ルーチンに入ったら残りのメモリをリークすることです)

検証

$ echo -n | valgrind perl
snip
==18517== 
==18517== LEAK SUMMARY:
==18517==    definitely lost: 8,134 bytes in 15 blocks
==18517==    indirectly lost: 154,523 bytes in 713 blocks
==18517==      possibly lost: 0 bytes in 0 blocks
==18517==    still reachable: 0 bytes in 0 blocks
==18517==         suppressed: 0 bytes in 0 blocks
==18517== 
==18517== For counts of detected and suppressed errors, rerun with: -v
==18517== ERROR SUMMARY: 15 errors from 15 contexts (suppressed: 0 from 0)

16
私はUnlambdaの答えが好きでしたが、これは(IMHO)あまりにもストレッチです、それは明らかにメモリをリークするインタープリター自体であるため、つまりperl --version、マシンで実行すると「間違いなく失われます:14ブロックで7,742バイト」、プログラムを実行することはまったくありませんが、
ツェッペリン

11
@zeppelin:同意しましたが、ルールによると、言語を定義するのは実装であるため、実装がメモリをリークすると、言語内のすべてのプログラムがメモリをリークします。私は必ずしもそのルールに同意するかどうかはわかりませんが、この時点では定着しすぎて本当に変更することができません。

8
これはNode JSでも機能します。
デニス

6
これは...作りの新しい標準抜け穴のように感じている
マイケル・ハンプトン

46
最後に、私が理解できるPerlスクリプト。
user11153

66

C、48 31 22バイト

警告:これを何度も実行しないでください。

たくさんの助け/アイデアをくれたデニスに感謝します!

f(k){shmget(k,1,512);}

これはさらに一歩進んでいます。shmgetプログラムの終了時に割り当て解除されない共有メモリを割り当てます。キーを使用してメモリを識別するため、初期化されていないintを使用します。これは技術的には未定義の動作ですが、実際には、これが呼び出されたときにスタックの最上部のすぐ上にある値を使用することを意味します。これは、次にスタックに何かが追加されたときに上書きされるため、キーは失われます。


これが機能しない唯一のケースは、以前にスタックにあったものを把握できる場合です。余分な19バイトについては、この問題を回避できます。

f(){srand(time(0));shmget(rand(),1,512);}

または、26バイトの場合:

main(k){shmget(&k,1,512);}

しかし、これでは、プログラムの終了後にメモリがリークします。プログラムの実行中はルールに反するメモリにアクセスできますが、プログラムの終了後、キーへのアクセスが失われ、メモリは引き続き割り当てられます。これには、アドレス空間レイアウトのランダム化(ASLR)が必要&kです。それ以外は常に同じです。現在、ASLRは通常デフォルトでオンになっています。


検証:

を使用ipcs -mして、システムに存在する共有メモリを確認できます。わかりやすくするために、既存のエントリを削除しました。

$ cat leakMem.c 
f(k){shmget(k,1,512);}
int main(){f();}     
$ gcc leakMem.c -o leakMem
leakMem.c:1:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 f(k){shmget(k,1,512);}
 ^
leakMem.c: In function ‘f’:
leakMem.c:1:1: warning: type of ‘k’ defaults to ‘int’ [-Wimplicit-int]
leakMem.c:1:6: warning: implicit declaration of function ‘shmget’ [-Wimplicit-function-declaration]
 f(k){shmget(k,1,512);}
ppcg:ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      


$ ./leakMem 

$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      

0x0000007b 3375157    Riley      0          1          0  

1
@AndrewSavinykh理論的には、shmidはファイルに保存されていた可能性があり、プログラムは将来的にファイルに添付することができました。これは... UNIXの共有メモリがどのように働くかある
tbodt

1
@AndrewSavinykh共有メモリは、基本的にOSが他のプロセスに提供できるリソースになります。これは、RAMに存在するファイルに似ており、名前(キー)を知っているプロセスは、削除されるまでアクセスできます。数値を計算してメモリに保存し、データを読み取るプロセスが共有メモリに接続する前に終了するプロセスを想像してください。この場合、OSがメモリを解放すると、2番目のプロセスはメモリを取得できません。
ライリー

35
これを投稿していただきありがとうございます。TIOを共有メモリリークから保護しただけです。
デニス

4
@Dennisそれが、TIOリンクを投稿しなかった理由です。保護されているかどうかは知りませんでした。
ライリー

12
問題という単語を使用して、プログラムが意図したよりも少ないメモリをリークするシナリオを説明する方法が好きです。
カスペルド

40

アンラムダc-refcnt/unlambda)、1バイト

i

オンラインでお試しください!

これは、非常に単純なプログラムでメモリをリークする既存のインタプリタを見つけることに関する本当に挑戦です。この場合、Unlambdaを使用しました。公式のUnlambdaインタープリターc-refcntは複数ありますが、ビルドが最も簡単なものの1つであり、プログラムが正常に実行されるとメモリリークが発生するという便利なプロパティがあります。したがって、ここで提供する必要があるのは、可能な限り単純な合法的Unlambdaプログラム、つまり操作なしでした。(空のプログラムはここでは動作しないことに注意してください;インタプリタがクラッシュした時点でメモリはまだ到達可能です。)

検証

$ wget ftp://ftp.madore.org/pub/madore/unlambda/unlambda-2.0.0.tar.gz
…をちょきちょきと切る…
2017-02-18 18:11:08(975 KB / s)-「unlambda-2.0.0.tar.gz」が保存されました[492894]
$ tar xf unlambda-2.0.0.tar.gz 
$ cd unlambda-2.0.0 / c-refcnt /
$ gcc unlambda.c
$ echo -ni | valgrind ./a.out / dev / stdin
…をちょきちょきと切る…
== 3417 ==リークの概要:
== 3417 ==間違いなく失われた:1ブロックで40バイト
== 3417 ==間接的に失われた:0ブロックに0バイト
== 3417 ==失われた可能性:0ブロックで0バイト
== 3417 ==それでも到達可能:0ブロックで0バイト
== 3417 ==抑制:0ブロックで0バイト
== 3417 == 
== 3417 ==検出および抑制されたエラーのカウントについては、-vで再実行します
== 3417 ==エラー概要:1コンテキストから1エラー(抑制:0から0)

39

TI-Basic、12バイト

While 1
Goto A
End
Lbl A
Pause 

「...メモリリークは、ループ内でGoto / Lblを使用するか、Endコマンドに到達する前に制御構造から飛び出すためにIf条件(Endコマンドを持つもの)を使用する場所です...」(詳細)


7
うわー、私はこれを覚えていると思います。私は私の古い基本的なプログラムで、私のループの飛び出し保ち、私のTI-84 +が遅く、遅くなったか気づいた...
レイ

2
うん、私たちのほとんどは気持ちを知っています;)@RayKoopa
Timtech

13
Ti Basicの場合は+1。私は9年生のほとんどをそれらのプログラミングに費やしました。
markasoftware

Pause 最後に必要ですか?2バイト節約できます。
kamoroso94

@ kamoroso94「プログラムが終了した場合、リークは解消され、それ以上の問題は発生しません」と考えているため、プログラムの終了を停止することになります。
ティムテック

32

Python <3.6.5、23バイト

property([]).__init__()

property.__init__漏洩の参照プロパティの古いfgetfsetfdel、と__doc__あなたはすでに初期化でそれを呼び出す場合property、インスタンス。これはバグであり、最終的にCPython 問題31787の一部として報告され、Python 3.6.5およびPython 3.7.0で修正されました。(また、はい、property([])あなたができることです。)


バグレポートが送信されましたか?
mbomb007


27

C#、34バイト

class L{~L(){for(;;)new L();}}

このソリューションでは、ヒープは必要ありません。本物の懸命に働くGC(Garbage Collector)が必要です。

基本的に、GCをそれ自身の敵に変えます。

説明

デストラクタが呼び出されるたびに、タイムアウトが実行される限り、この邪悪なクラスの新しいインスタンスが作成され、デストラクタの終了を待たずにそのオブジェクトを破棄するようにGCに指示します。それまでに、数千の新しいインスタンスが作成されました。

これの「悪さ」は、GCの動作が激しくなればなるほど、これがあなたの顔に吹き荒れることです。

免責事項:あなたのGCは私のものよりも賢いかもしれません。プログラムの他の状況により、GCは最初のオブジェクトまたはそのデストラクタを無視する場合があります。これらの場合、これは爆発しません。しかし、多くのバリエーションでそうなります。ここに数バイトを追加すると、あらゆる状況でリークが発生する可能性があります。多分電源スイッチを除いて。

テスト

テストスイートは次のとおりです。

using System;
using System.Threading;
using System.Diagnostics;
class LeakTest {
    public static void Main() {
        SpawnLeakage();
        Console.WriteLine("{0}-: Objects may be freed now", DateTime.Now);
        // any managed object created in SpawbLeakage 
        //  is no longer accessible
        // The GC should take care of them

        // Now let's see
        MonitorGC();
    }
    public static void SpawnLeakage() {
        Console.WriteLine("{0}-: Creating 'leakage' object", DateTime.Now);
        L l = new L();
    }
    public static void MonitorGC() {
        while(true) {
            int top = Console.CursorTop;
            int left = Console.CursorLeft;
            Console.WriteLine(
                "{0}-: Total managed memory: {1} bytes",
                DateTime.Now,
                GC.GetTotalMemory(false)
            );
            Console.SetCursorPosition(left, top);
        }
    }
}

10分後の出力:

2/19/2017 2:12:18 PM-: Creating 'leakage' object
2/19/2017 2:12:18 PM-: Objects may be freed now
2/19/2017 2:22:36 PM-: Total managed memory: 2684476624 bytes

これは2 684 476 624バイトです。WorkingSetプロセスの合計は約4.8 GBでした

この答えは、Eric Lippertのすばらしい記事「あなたが知っていることがすべて間違っているとき」に触発されまし


これは魅力的です。ガベージコレクターは、いくつかのものが存在することを「忘れて」、このためにそれらを追跡できなくなりますか?私はc#についてあまり知りません。また、今私は、爆弾と漏れの違いは何ですか?私は...同様の大失敗は、技術的には、システムがこれらの参照のトラックを失うことはありませんが、それだけでスペースを使い果たし、コンストラクタの内部からのコンストラクタを呼び出す、または停止したことがない無限再帰機能を持つことによって作成することができます想像
ドン明るい

1
コンストラクター内のコンストラクターは、スタックオーバーフローを引き起こします。しかし、インスタンスのデストラクタはフラットな階層で呼び出されます。GCは実際にオブジェクトの追跡を失うことはありません。それらを破壊しようとするたびに、知らないうちに新しいオブジェクトを作成します。一方、ユーザーコードは、上記のオブジェクトにアクセスできません。また、GCはデストラクタを呼び出さずにオブジェクトを破棄することを決定する可能性があるため、前述の矛盾が発生する可能性があります。
MrPaulch

使用するだけでチャレンジは完了しませんclass L{~L(){new L();}}か?知るfor(;;)限りでは、メモリリークが速くなりますよね?
BgrWorker

1
悲しいことに、いいえ。破壊されたオブジェクトごとに新しいインスタンスが1つだけ作成されるため、再びアクセスできなくなり、破壊のマークが付けられます。繰り返す。破棄が保留されているオブジェクトは1つだけです。人口の増加はありません。
MrPaulch

2
あんまり。最終的に1つのファイナライズは無視されます。関係なく、対応するオブジェクトが食べられます。
MrPaulch

26

C(gcc)、15バイト

f(){malloc(1);}

検証

$ cat leak.c
f(){malloc(1);}
main(){f();}
$ gcc -g -o leak leak.c
leak.c: In function ‘f’:
leak.c:1:5: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
 f(){malloc(1);}
     ^
$ valgrind --leak-check=full ./leak
==32091== Memcheck, a memory error detector
==32091== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==32091== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==32091== Command: ./leak
==32091==
==32091==
==32091== HEAP SUMMARY:
==32091==     in use at exit: 1 bytes in 1 blocks
==32091==   total heap usage: 1 allocs, 0 frees, 1 bytes allocated
==32091==
==32091== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1
==32091==    at 0x4C29110: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==32091==    by 0x40056A: f (leak.c:1)
==32091==    by 0x40057A: main (leak.c:2)
==32091==
==32091== LEAK SUMMARY:
==32091==    definitely lost: 1 bytes in 1 blocks
==32091==    indirectly lost: 0 bytes in 0 blocks
==32091==      possibly lost: 0 bytes in 0 blocks
==32091==    still reachable: 0 bytes in 0 blocks
==32091==         suppressed: 0 bytes in 0 blocks
==32091==
==32091== For counts of detected and suppressed errors, rerun with: -v
==32091== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

26

Javascript、14バイト

ゴルフ

setInterval(0)

空のインターバルハンドラをデフォルトの遅延で登録し、結果のタイマーIDを破棄します(キャンセルできなくなります)。

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

デフォルトの間隔を使用するとCPUが狂ったように消費されるため、リークを説明するために、デフォルト以外の間隔を使用して数百万のタイマーを作成しました。


5
母は、私はあなたが「Golfed」入力したことを愛する、ungolfedバージョンについて、私は好奇心旺盛になり
マルタイン

9
それは次のようになりますif(window && window.setInterval && typeof window.setInterval === 'function') { window.setInterval(0); }
Tschallacka

3
実際、これはキャンセルすることは不可能ではありません。間隔(およびタイムアウト)IDには順番に番号が付けられるためclearInterval、間隔がなくなるまでIDを増分して呼び出すだけで簡単にキャンセルできます。例:for(let i=0;i<1e5;i++){try{clearInterval(i);}catch(ex){}}
user2428118

5
@ツェッペリンとしてuser2428118が、これはもうあなたに力コールをブルート可能性があるため、C / C ++の漏れが「本物」ではありませんと言っ以下「legitmate」である、と言うんfree()
TripeHound

1
JavaScriptが...実際の候補であるうわー、多くのない挑戦
ジャレッド・スミス

19

Java、10バイト

最後に、Javaでの競争力のある答えです!

ゴルフ

". "::trim

これは(文字列定数に対する)メソッド参照であり、次のように使用できます。

Supplier<String> r = ". "::trim

リテラル文字列". "は、クラスによって維持されるように、グローバルなインターンされた文字列プールに自動的に追加され、java.lang.Stringすぐにトリムするため、その参照はコードでさらに再利用できません(同じ文字列を再度宣言しない限り)。

...

最初は空の文字列のプールは、クラスStringによってプライベートに保持されます。

すべてのリテラル文字列と文字列値の定数式はインターンされます。文字列リテラルは、Java™言語仕様のセクション3.10.5で定義されています。

...

https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#intern--

文字列を自身に追加し、ループ内で明示的にintern()メソッドを呼び出すことにより、「プロダクショングレード」のメモリリークでこれを有効にできます。


2
私はこれをC#について考えました...しかし、あなたが言うように別の文字列リテラルを含めることでそのメモリにアクセスできるので、それは重要ではないと思います。また、何("." + " ").intern()ができるかを知りたいと思います(それらがユーザー入力またはw / eであった場合、コンパイラーの最適化を無視します)。
VisualMelon

1
確かに、唯一のコンセンサスはせいぜいスリムで、私は「コードがコンパイルされるべき」という側面にしっかりと取り組んでいます。私はまだ私が(これらの文字列は、問題の文言与えられたこのソリューションを購入するかわからないことはできません解放され、そして、彼らはすることができ、それはそうだにもかかわらず、正常な動作コードで見つけること)が、私は自分自身の判断をするために他のユーザーを招待します
VisualMelon

3
その文字列はアクセス不能でさえありません、もちろん漏れます。等しい文字列をインターンすることで、いつでも取得できます。これがカウントされる場合、未使用のグローバル変数(Javaのプライベートスタティック)はリークになります。これは、メモリリークの定義方法ではありません。
user2357112

3
@ user2357112 "...その文字列にアクセスすることすらできない..." ここで、このメソッド参照X()をコードの引数として取得し、内部で文字列リテラルを割り当てる(およびインターンする)ことは知っていますが、どちらが「。」または「123」であるかは正確にはわかりませんまたは(一般的に)未知の長さの他の文字列。引き続きアクセスする方法をデモンストレーションしますか、それが占有する「インターン」プールのエントリの割り当てを解除しますか?
ツェッペリン

2
@ user2357112有限のメモリを持つマシンでは、任意のメモリに格納されている値にアクセスできますsimply by guessing it correctlyが、それはメモリリークなどが存在しないという意味ではありません。there's probably some way to use reflection to determine the string's contents tooこれを実証できますか?(ヒント、String.intern()はネイティブコードに実装されています)。
ツェッペリン

17

さび、52バイト

extern{fn malloc(_:u8);}fn main(){unsafe{malloc(9)}}

システムmallocでいくつかのバイトを割り当てます。これは、間違ったABIが受け入れられることを前提としています。


Rust(理論上)、38バイト

fn main(){Box::into_raw(Box::new(1));}

ヒープにメモリを割り当て、生のポインタを抽出し、それを無視して事実上リークします。(Box::into_rawより短いstd::mem::forget)。

ただし、Rustはデフォルトでjemallocを使用しますが、valgrindは漏れを検出できません。システムアロケータに切り替えることもできますが、これにより50バイト追加され、毎晩必要になります。メモリの安全性に感謝します。


最初のプログラムの出力:

==10228== Memcheck, a memory error detector
==10228== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==10228== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==10228== Command: ./1
==10228== 
==10228== 
==10228== HEAP SUMMARY:
==10228==     in use at exit: 9 bytes in 1 blocks
==10228==   total heap usage: 7 allocs, 6 frees, 2,009 bytes allocated
==10228== 
==10228== LEAK SUMMARY:
==10228==    definitely lost: 9 bytes in 1 blocks
==10228==    indirectly lost: 0 bytes in 0 blocks
==10228==      possibly lost: 0 bytes in 0 blocks
==10228==    still reachable: 0 bytes in 0 blocks
==10228==         suppressed: 0 bytes in 0 blocks
==10228== Rerun with --leak-check=full to see details of leaked memory
==10228== 
==10228== For counts of detected and suppressed errors, rerun with: -v
==10228== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

驚くばかり。このような投稿は、私が過去1年にわたってRustを探求するきっかけとなりました。
明るい

16

8086 ASM、3バイト

この例では、Cランタイムがリンクされていることを前提としています。

jmp _malloc

これは、の相対アドレスがe9 XX XXどこにあるかを組み立てXX XXます_malloc

これによりmalloc、予測不可能な量のメモリが割り当てられ、すぐに戻ってプロセスが終了します。DOSのような一部のオペレーティングシステムでは、システムが再起動されるまでメモリがまったく再利用できない場合があります。


mallocの通常の実装では、プロセスの終了時にメモリが解放されます。
ジョシュア

@Joshua Yeah、しかしそれは実装定義の振る舞いです。
FUZxxl

12

4番目、6バイト

ゴルフ

s" " *

空の文字列をs" "で割り当て、そのアドレスと長さ(0)をスタックに残し、それらを乗算します(結果としてメモリアドレスが失われます)。

ヴァルグラインド

%valgrind --leak-check=full gforth -e 's" " * bye'
...
==12788== HEAP SUMMARY:
==12788==     in use at exit: 223,855 bytes in 3,129 blocks
==12788==   total heap usage: 7,289 allocs, 4,160 frees, 552,500 bytes allocated
==12788== 
==12788== 1 bytes in 1 blocks are definitely lost in loss record 1 of 22
==12788==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12788==    by 0x406E39: gforth_engine (in /usr/bin/gforth-0.7.0)
==12788==    by 0x41156A: gforth_go (in /usr/bin/gforth-0.7.0)
==12788==    by 0x403F9A: main (in /usr/bin/gforth-0.7.0)
==12788== 
...
==12818== LEAK SUMMARY:
==12818==    definitely lost: 1 bytes in 1 blocks
==12818==    indirectly lost: 0 bytes in 0 blocks

10

45バイト行く

package main
func main(){go func(){for{}}()}

これにより、内部に無限ループを持つ匿名ゴルーチンが作成されます。ゴルーチンを開始することは、同時に実行される小さなスレッドを生成するようなものであるため、プログラムは通常どおり実行を続けることができますが、プログラムにはゴルーチンに割り当てられたメモリを再利用する方法がありません。ガベージコレクターはまだ実行中のため、収集することもありません。これを「ゴルーチンを漏らす」と呼ぶ人もいます


ゴルフのチェックは:これは呼び出しよりも2バイト短いC.malloc(8)あなたがする必要があるため、import"C"
Riking

9

Java 1.3、23バイト

void l(){new Thread();}

スレッドを作成しますが、開始しません。スレッドは内部スレッドプールに登録されますが、開始されることはないため、終了することはないため、GCの候補になることはありません。これは取得できないオブジェクトであり、Javaの限界にとらわれています。

それは後で修正されたため、1.3が含まれるまでのJavaのバグです。

テスト中

次のプログラムは、必ず新しいスレッドオブジェクトでメモリを汚染し、空きメモリスペースの減少を示します。リークテストのために、GCを集中的に実行します。

public class Pcg110485 {

    static
    void l(){new Thread();}

    public static void main(String[] args) {

        while(true){
            l();
            System.gc();
            System.out.println(Runtime.getRuntime().freeMemory());
        }
    }
}

これは特定のJavaバージョンでのみ機能するため、代わりにヘッダーで「Java 3」と言う必要があります。

5
Java 3のようなものはありません。それはJava 1.3です。Java 1.0、1.1、2、1.3、1.4、5、6、7、8、9がありました。
オリビエグレゴワール

これも私の考えでした。くそー。
魔法のタコUr

8

Befunge(fungi)、1バイト

$

これはプラットフォームに依存し、バージョンに依存する可能性があります(Windowsではバージョン1.0.4でのみテストしました)が、真菌は歴史的に非常に漏れやすいインタープリターでした。$(ドロップ)コマンドは、空のスタックに何もしないはずですが、このコードをループするには、何らかの形で非常に迅速に多くのメモリをリークし管理しています。数秒のうちに、数回のギグを使い果たし、「メモリ不足」エラーでクラッシュします。

必ずしも$コマンドである必要はないことに注意してください-ほぼ何でもできます。ただし、空のソースファイルでは機能しません。少なくとも1つの操作が必要です。


8

Swift 3、38バイト

新しいバージョン:

class X{var x: X!};do{let x=X();x.x=x}

x 自身への強い参照があるため、割り当てが解除されず、メモリリークが発生します。

旧版:

class X{var y:Y!}
class Y{var x:X!}
do{let x=X();let y=Y();x.y=y;y.x=x}

xへの強い参照が含まれていyます。したがって、どちらも割り当て解除されず、メモリリークが発生します。


うーん、あなたはまだを通じてそのメモリを参照することができますxし、y(あなたが何らかの形でそれらを破壊しない限り)ので、これは本当に私にリークのようには見えません。
ツェッペリン

最後の行は、それを修正する機能でラップすることができ@zeppelin
NobodyNada

@NobodyNada、もしdoツェッペリンが正しかった問題を解決するブロックの最後の行を置くとしたら?
ダニエル

@Dopappうん; do同様に動作します。良いアイデア!
NobodyNada

これを短縮することができる、あなたは、2つのクラスを必要としない- Xは、自分自身への参照を保持することができますclass X{var x: X!};do{let x=X();x.x=x}
セバスチャンOsiński

7

Delphi(Object Pascal)-33バイト

変数なしのオブジェクト、フルコンソールプログラムの作成:

program;begin TObject.Create;end.

プロジェクトでFastMM4を有効にすると、メモリリークが表示されます。

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


6

C#-84バイト

class P{static void Main(){System.Runtime.InteropServices.Marshal.AllocHGlobal(1);}}

これにより、管理されていないメモリがちょうど1バイト割り当てられ、それを失うIntPtrことになります。ループに詰め込み、アプリケーションがクラッシュするのを待つことでテストできます(速度を上げるためにゼロをいくつか追加したい場合があります)。

私はSystem.IO.File.Create("a");そのように考えましたが、アプリケーション自体メモリ収集するため、これらは必ずしもメモリリークであるとは確信していません(リークする可能性があるCloseDispose、呼び出されなかったため)ファイルアクセスにはファイルシステムのアクセス許可も必要であり、誰もそれらに依存することを望みません。そして、ファイナライザーが呼び出されるのを止めるものはないため(これにより、基になるリソースが解放されます)、フレームワークはこれらの種類の判断の誤りを(ある程度)緩和するために含まれるため、プログラマを、一見非決定的なファイルロック(混乱している場合)と混同します。Jon Hannaに感謝します。

もっと短い方法が見つからないのは少し残念です。.NET GCは動作しますがIDisposables、mscorlibで間違いなくリークするものは考えられません(実際、それらはすべてファイナライザを持っているようです、どれほど厄介です)、私はアンマネージドメモリを割り当てる他の方法を知りません)、および反射)(言語に関係なくセマンティクスの(無アクセサと例えばプライベートメンバーまたはクラス)、それを参照して何かを確実にすることができたこと。


1
System.IO.File.Create("a")何もリークしGC.SuppressFinalize(System.IO.File.Create("a"))ませんが、プロデューサーのファイナライザーを実行しないように明示的に求められFileStreamます。
ジョンハンナ

@JonHannaかなり正しい。私のIDisposableパラノイアは私を良くしたようです。
VisualMelon

System.Drawing.Bitmapを使用してGDI +をリークする可能性があります。プログラム自体ではなく、リークの原因となっているWindowsライブラリであるため、カウントされるかどうかはわかりません。
BgrWorker

@BgrWorkerには間違いなくファイナライザーもあり、コストのコンセンサスに同意しないため、コードゴルフの外部ライブラリを避ける傾向があります:自信がある方法を見つけられるなら、気軽に投稿してくださいあなた自身の答えで!
VisualMelon

<!-- language: lang-c# -->これと素晴らしい答えをありがとう!(C#なので、大好きです)
Metoniem

5

ファクター、13バイト

Factorは自動メモリ管理を備えていますが、libc機能へのアクセスも提供します。

1 malloc drop

1バイトのメモリを手動で割り当て、そのアドレスを返し、ドロップします。

malloc 実際にコピーを登録してメモリリークとダブルフリーを追跡しますが、リークしたものを特定するのは簡単な作業ではありません。

本当にその参照を失うことを確認したい場合:

1 (malloc) drop

sayでリークをテストする[ 1 malloc drop ] leaks.

| Disposable class | Instances |                    |
| malloc-ptr       | 1         | [ List instances ] |

sayでリークをテストする[ 1 (malloc) drop ] leaks.

| Disposable class | Instances | |

大野!悪い要因、それは今アルツハイマー病を持っています!D:


5

Common Lisp(SBCLのみ)、 28 26バイト

sb-alien::(make-alien int)

次のように実行しsbcl --eval 'sb-alien::(make-alien int)'ます。何も出力も返されませんが、メモリ割り当ては発生します。フォームを内にラップする(print ...)と、ポインターがREPLに表示されます。

  1. package::(form)は、フォームの読み取り中に現在のパッケージを一時的にバインドするためのSBCLの特別な表記です。これは、両方の接頭辞を避けるために、ここで使用されているmake-alienintしてsb-alien。現在のパッケージがこのパッケージに設定されていると仮定するのはごまかしだと思います。起動時にはそうではないからです。

  2. make-alien 特定のタイプとオプションのサイズにメモリを割り当てます(mallocを使用)。

  3. REPLでこれを実行する場合0、REPLがポインターではなくその値を返すように、割り当ての後に追加します。REPLは最後の3つの返された値が(参照してください覚えているので、そうでない場合、それは本当漏れないだろう******)と我々はまだ割り当てられたメモリを解放する機会を持つことができます。

PrzemysławPのおかげで2バイトが削除されました、ありがとう!


1
あなたは使用できません1(または23など)の代わりに、()あなたが値を返すように1?1バイト節約されます。また、この回答はREPLのみですか?コードをロードするload場合()、最後に含めることはできませんか?
PrzemysławP

1
@PrzemysławPあなたは両方の点で正しいです、私は試しましたがeval、これはあなたが言ったように機能します。どうもありがとう!
コアダンプ

4

AutoIt、39バイト

#include<Memory.au3>
_MemGlobalAlloc(1)

ヒープから1バイトを割り当てます。によって返されるハンドル_MemGlobalAllocは破棄されるため、その割り当てを明示的に解放する方法はありません。


3

C ++、16バイト

main(){new int;}

リークをチェックするためのvalgrindはありませんが、そうすべきだと確信しています。そうでなければ私は試してみます:

main(){[]{new int;}();}

バルグラインド結果

(確かに漏れます)

==708== LEAK SUMMARY:
==708==    definitely lost: 4 bytes in 1 blocks

@WheatWizardを使用していますg++ 4.3.2(最新のものではありません)。intデフォルトでは戻り値の型はありません。-Wall私も警告を持っている:plop.cpp:1: warning: ISO C++ forbids declaration of 'main' with no type
matovitch

2
@WheatWizard申し訳ありませんが、コンテストを開始するためのc ++の例を紹介しました。redditから来て、私は答えを見ただけで、(奇妙なことに)C ++は見ませんでした。私は少し愚かな感じがします。:/
マトビッチ

コンセンサスは[]{new int;}、C ++関数と同様に数えることができるということです(チャレンジはプログラム全体を指定しませんでした)。
トビースパイト

3

Java(OpenJDK 9)322 220バイト

import sun.misc.*;class Main{static void main(String[]a)throws Exception{java.lang.reflect.Field f=Unsafe.class.getDeclaredField("theUnsafe");f.setAccessible‌​(1<2);((Unsafe)f.get‌​(1)).allocateMemory(‌​1);}}

オンラインでお試しください!

これは、文字列キャッシュを使用しない別のメモリリークです。それはあなたのRAMの半分を割り当てます、そして、あなたはそれで何もすることができません。

すべてのバイトを保存してくれたzeppelinに感謝


あなたは取得することにより、バイトの束を保存することができますUnsafe:そのような、その中に静的変数からインスタンスをimport sun.misc.*;class M{static void main(String[]a)throws Exception{java.lang.reflect.Field f=Unsafe.class.getDeclaredField("theUnsafe");f.setAccessible(1<2);((Unsafe)f.get(1)).allocateMemory(1);}}
ツェッペリン

またpublic static void main、静的イニシャライザで置き換えることにより、さらに節約static{try{}catch(Exception e){}}できます(起動するのは少し難しいかもしれませんが、それでも有効でコンパイル可能です)。
ツェッペリン

yheaコンストラクターの使用は、使用したコードのAndroidバージョンで使用されていました。私は@homeのときにいくつかのことを変更しますが、1つのステートメントであなたが行ったパスに行きます;)
Serverfrog

空白を削除し、のa代わりに使用してargs、パブリックを削除します。tio.run/nexus/...
パベル

trueは1> 0に置き換えることができます
masterX244

3

c、9バイト

main(){}

証明:

localhost/home/elronnd-10061: cat t.c
main(){}
localhost/home/elronnd-10062: valgrind gcc t.c
==10092== Memcheck, a memory error detector
==10092== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==10092== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==10092== Command: gcc t.c
==10092==
t.c:1:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 main(){}
 ^~~~
==10092==
==10092== HEAP SUMMARY:
==10092==     in use at exit: 178,518 bytes in 73 blocks
==10092==   total heap usage: 362 allocs, 289 frees, 230,415 bytes allocated
==10092==
==10092== LEAK SUMMARY:
==10092==    definitely lost: 4,659 bytes in 8 blocks
==10092==    indirectly lost: 82 bytes in 5 blocks
==10092==      possibly lost: 0 bytes in 0 blocks
==10092==    still reachable: 173,777 bytes in 60 blocks
==10092==         suppressed: 0 bytes in 0 blocks
==10092== Rerun with --leak-check=full to see details of leaked memory
==10092==
==10092== For counts of detected and suppressed errors, rerun with: -v
==10092== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

1
実際にメモリをリークしているわけではありません。gccです。これは空のプログラムでも動作するはずです。試してみてくださいgcc src.c && valgrind ./a.out。きれいな結果が得られます。

3

C#、109バイト

public class P{static void Main({for(;;)System.Xml.Serialization.XmlSerializer.FromTypes(new[]{typeof(P)});}}

本番コードでこのリークの背後にあるアイデアを見つけ、それを調査してこの記事に至ります。主な問題は、記事からのこの長い引用にあります(詳細についてはそれを読んでください):

PurchaseOrderでコードを検索するpage_loadと、ページの1 つでこのコード行が見つかりますXmlSerializer serializer = new XmlSerializer(typeof(PurchaseOrder), new XmlRootAttribute(“”));

これはかなり無邪気なコードのように思えます。を作成XMLSerializerPurchaseOrderます。しかし、カバーの下で何が起こるのでしょうか?

XmlSerializerReflectorを使用してコンストラクターを見ると、this.tempAssembly = XmlSerializer.GenerateTempAssembly(this.mapping, type, defaultNamespace, location, evidence);temp(動的)アセンブリを生成する呼び出しが行われていることがわかります。したがって、このコードが実行されるたびに(つまり、ページがヒットするたびに)、新しいアセンブリが生成されます。

アセンブリを生成する理由は、シリアライズおよびデシリアライズのための関数を生成する必要があり、これらはどこかに存在する必要があるためです。

わかりました。アセンブリを作成します。それが終わったら、それはちょうど消えるはずです?

さて...アセンブリはGCヒープ上のオブジェクトではありません。GCは実際にはアセンブリを認識しないため、ガベージコレクションは行われません。1.0および1.1でアセンブリを削除する唯一の方法は、アセンブリが存在するアプリドメインをアンロードすることです。

そしてそこにはワトソン博士の問題があります。

Visual Studio 2015のコンパイラから実行し、診断ツールウィンドウを使用すると、約38秒後に次の結果が表示されます。プロセスメモリが着実に上昇し、ガベージコレクター(GC)が実行し続けますが、何も収集できないことに注意してください。

診断ツールウィンドウ


2

C 30バイト

f(){int *i=malloc(sizeof(4));}

Valgrindの結果:

         ==26311== HEAP SUMMARY:
         ==26311==     in use at exit: 4 bytes in 1 blocks
         ==26311==   total heap usage: 1 allocs, 0 frees, 4 bytes allocated
         ==26311== 
         ==26311== LEAK SUMMARY:
         ==26311==    definitely lost: 4 bytes in 1 blocks
         ==26311==    indirectly lost: 0 bytes in 0 blocks
         ==26311==      possibly lost: 0 bytes in 0 blocks
         ==26311==    still reachable: 0 bytes in 0 blocks
         ==26311==         suppressed: 0 bytes in 0 blocks
         ==26311== Rerun with --leak-check=full to see details of leaked memory

2
代わりに単にすることは可能main(){malloc(1);}ですか?
kirbyfan64sos

@そうだね!しかし、すでに投稿されています!
アベルトム・

2

ダーツ、76バイト

import'dart:async';main()=>new Stream.periodic(Duration.ZERO).listen((_){});

JavaScriptの答えに少し似ています。.listenDartストリームオブジェクトを呼び出すと、StreamSubscriptionが返されます。これにより、ストリームから切断できます。ただし、それを捨てると、ストリームのサブスクリプションを解除できなくなり、リークが発生します。リークを修正できる唯一の方法は、Stream自体が収集されるが、StreamController + Timerコンボによって内部的に参照される場合です。

残念ながら、Dartは私が試した他のものにはあまりにも賢いです。()async=>await new Completer().futureawaitの使用はdoと同じであるため機能しませんnew Completer().future.then(<continuation>)。これにより、2番目のCompleterが参照されないため、クロージャー自体を破棄できます(Completerは.futureFutureの参照を保持し、Futureはクロージャーとしての継続への参照を保持します)。

また、分離(スレッドとも呼ばれます)はGCによってクリーンアップされるため、新しいスレッドで自分自身を生成してすぐに一時停止(import'dart:isolate';main(_)=>Isolate.spawn(main,0,paused:true);)することはできません。分離ループを無限ループ(import'dart:isolate';f(_){while(true){print('x');}}main()=>Isolate.spawn(f,0);)で生成しても、分離は強制終了され、プログラムは終了します。

しかたがない。


メインプログラムが実行され続け、他のことをしている場合、ガベージコレクターは分離を停止することができますか?私のゴルーチンの例が似ているように聞こえるので尋ねます...プログラムが終了してOSにすべてのメモリを戻すという事実は、必ずしもリークしていないことを意味するとは限りません。
明るくしない

2

Swift、12バイト

[3,5][0...0]

説明:

これは事実上のメモリリークであり、その言語でメモリの手動管理、自動参照カウント(ARC、Swiftなど)、またはスイープガベージコレクションを使用している場合でも、どの言語でも発生する可能性があります。

[3,5]単なる配列リテラルです。この配列は、少なくともこれらの2つの要素に十分なメモリを割り当てます。3そして5ちょうど任意です。

添え字(インデックス)をArray<T>生成しArraySlice<T>ます。アンはArraySlice<T>それから作成されたアレイのメモリへのビューです。

[3,5][0...0]を生成しArraySlice<Int>、その値は[3]です。3このスライスの3要素、コピーではなく、上記3の元の要素と同じ要素であることに注意してください。Array

結果のスライスは、変数に保存して使用できます。元の配列はもう参照されていないため、割り当てを解除できると思われます。ただし、できません。

スライスは元の配列のメモリにビューを公開するため、スライスが存在する限り元の配列を維持する必要があります。したがって、2割り当てられた元の要素サイズのメモリのうち、最初の要素サイズのメモリのみが使用され、もう1つは最初の要素サイズを割り当てないために存在する必要があります。メモリの2番目の要素サイズはデファクターリークです。

この問題の解決策は、大きな配列の小さなスライスを長時間維持しないことです。スライスの内容を保持する必要がある場合は、スライスに配列を昇格させます。これにより、メモリのコピーがトリガーされ、元の配列のメモリへの依存性がなくなります。

Array([3,5][0...0])

2

解決策1:C(Mac OS X x86_64)、109バイト

golf_sol1.cのソース

main[]={142510920,2336753547,3505849471,284148040,2370322315,2314740852,1351437506,1208291319,914962059,195};

上記のプログラムは、__ DATAセグメントの実行アクセスでコンパイルする必要があります。

clang golf_sol1.c -o golf_sol1 -Xlinker -segprot -Xlinker __DATA -Xlinker rwx -Xlinker rwx

次に、プログラムを実行するには、次を実行します。

./golf_sol1 $(ruby -e 'puts "\xf5\xff\xff\xfe\xff\xff\x44\x82\x57\x7d\xff\x7f"')

結果:

残念ながら、Valgrindはシステムコールから割り当てられたメモリを監視しないため、検出されたリークを表示できません。

ただし、vmmapを見て、割り当てられたメモリの大きなチャンク(MALLOCメタデータ)を確認できます。

                                VIRTUAL   REGION 
REGION TYPE                        SIZE    COUNT (non-coalesced) 
===========                     =======  ======= 
Kernel Alloc Once                    4K        2 
MALLOC guard page                   16K        4 
MALLOC metadata                   16.2M        7 
MALLOC_SMALL                      8192K        2         see MALLOC ZONE table below
MALLOC_TINY                       1024K        2         see MALLOC ZONE table below
STACK GUARD                       56.0M        2 
Stack                             8192K        3 
VM_ALLOCATE (reserved)             520K        3         reserved VM address space (unallocated)
__DATA                             684K       42 
__LINKEDIT                        70.8M        4 
__TEXT                            5960K       44 
shared memory                        8K        3 
===========                     =======  ======= 
TOTAL                            167.0M      106 
TOTAL, minus reserved VM space   166.5M      106 

説明

したがって、改善されたソリューションに進む前に、ここで実際に何が起こっているのかを説明する必要があると思います。

この主な機能は、Cの欠落している型宣言(したがって、文字を書くことを無駄にすることなくデフォルトでintになります)およびシンボルの動作を乱用しています。リンカはmain、呼び出すために呼び出されるシンボルを見つけることができるかどうかだけを考慮します。したがって、ここではmainをintの配列にして、実行するシェルコードで初期化します。このため、mainは__TEXTセグメントではなく__DATAセグメントに追加されるため、実行可能な__DATAセグメントを使用してプログラムをコンパイルする必要があります。

mainにあるシェルコードは次のとおりです。

movq 8(%rsi), %rdi
movl (%rdi), %eax
movq 4(%rdi), %rdi
notl %eax
shrq $16, %rdi
movl (%rdi), %edi
leaq -0x8(%rsp), %rsi
movl %eax, %edx
leaq -9(%rax), %r10
syscall
movq (%rsi), %rsi
movl %esi, (%rsi)
ret

これは、メモリのページを割り当てるためにsyscall関数を呼び出すことです(syscall mach_vm_allocateは内部的に使用します)。RAXは0x100000a(必要な関数をsyscallに伝えます)である必要がありますが、RDIは割り当てのターゲットを保持します(この場合、mach_task_self()になります)、RSIはアドレスを保持して、新しく作成されたメモリへのポインターを書き込む必要があります(つまり、スタック上のセクションを指しているだけです)、RDXは割り当てのサイズを保持しています(バイトを節約するためにRAXまたは0x100000aを渡しているだけです)、R10はフラグを保持しています(できることを示しています)どこにでも割り当てられます)。

今では、RAXとRDIがどこから値を取得しているかは明白ではありません。RAXは0x100000aである必要があり、RDIはmach_task_self()が返す値である必要があることを知っています。幸いなことに、mach_task_self()は実際には変数(mach_task_self_)のマクロであり、毎回同じメモリアドレスにあります(ただし、再起動時に変更する必要があります)。私の特定のインスタンスでは、mach_task_self_がたまたま0x00007fff7d578244にあります。そのため、指示を減らすために、代わりにこのデータをargvから渡します。これが、この式でプログラムを実行する理由です$(ruby -e 'puts "\xf5\xff\xff\xfe\xff\xff\x44\x82\x57\x7d\xff\x7f"')最初の引数。文字列は2つの値を組み合わせたものです。RAX値(0x100000a)は32ビットのみで、1の補数が適用されています(したがって、nullバイトはありません。元の値を取得するための値ではありません)、次の値はRDI(0x00007fff7d578244)が左にシフトされ、最後に2つの余分なジャンクバイトが追加されています(再びnullバイトを除外するために、元に戻すには右にシフトします)。

syscallの後、新しく割り当てられたメモリに書き込みます。これは、mach_vm_allocate(またはこのsyscall)を使用して割り当てられたメモリが実際にはVMページであり、自動的にメモリにページングされないためです。むしろ、データが書き込まれるまで予約され、それらのページはメモリにマップされます。予約されているだけで要件を満たしているかどうかはわかりませんでした。

次のソリューションでは、シェルコードにヌルバイトがないため、プログラムのコードの外にシェルコードを移動してサイズを小さくできるという事実を活用します。

解決策2:C(Mac OS X x86_64)、44バイト

golf_sol2.cのソース

main[]={141986632,10937,1032669184,2,42227};

上記のプログラムは、__ DATAセグメントの実行アクセスでコンパイルする必要があります。

clang golf_sol2.c -o golf_sol2 -Xlinker -segprot -Xlinker __DATA -Xlinker rwx -Xlinker rwx

次に、プログラムを実行するには、次を実行します。

./golf_sol2 $(ruby -e 'puts "\xb8\xf5\xff\xff\xfe\xf7\xd0\x48\xbf\xff\xff\x44\x82\x57\x7d\xff\x7f\x48\xc1\xef\x10\x8b\x3f\x48\x8d\x74\x24\xf8\x89\xc2\x4c\x8d\x50\xf7\x0f\x05\x48\x8b\x36\x89\x36\xc3"')

同じサイズの割り当てを行っているため、結果は以前と同じになります。

説明

ソリューション1とほぼ同じ概念に従いますが、例外は、コードの一部をプログラムの外部に移動したことです。

mainにあるシェルコードは次のとおりです。

movq 8(%rsi), %rsi
movl $42, %ecx
leaq 2(%rip), %rdi
rep movsb (%rsi), (%rdi)

これは基本的に、argvで渡したシェルコードをコピーしてこのコードの後に​​配置します(したがって、コピーした後、挿入されたシェルコードを実行します)。私たちにとって有利なのは、__ DATAセグメントが少なくともページサイズになるため、コードがそれほど大きくなくても、「安全に」さらに書き込むことができるということです。欠点はここでは理想的なソリューションであり、コピーさえ必要とせず、代わりにargvのシェルコードを直接呼び出して実行するだけです。しかし、残念ながら、このメモリには実行権がありません。このメモリの権限を変更できますが、単にコピーするよりも多くのコードが必要になります。別の戦略は、外部プログラムから権利を変更することです(詳細は後で説明します)。

argvに渡すシェルコードは次のとおりです。

movl $0xfefffff5, %eax
notl %eax
movq $0x7fff7d578244ffff, %rdi
shrq $16, %rdi
movl (%rdi), %edi
leaq -0x8(%rsp), %rsi
movl %eax, %edx
leaq -9(%rax), %r10
syscall
movq (%rsi), %rsi
movl %esi, (%rsi)
ret

これは以前のコードとほとんど同じですが、唯一の違いは、EAXとRDIの値を直接含めていることです。

考えられる解決策1:C(Mac OS X x86_64)、11バイト

プログラムを外部で変更するという考え方は、外部プログラムにリークを移動する可能性のある解決策を提供します。実際のプログラム(サブミッション)は単なるダミープログラムであり、リークプログラムはターゲットプログラムにメモリを割り当てます。今、私はこれがこのチャレンジのルールに当てはまるかどうかはわかりませんでしたが、それでもそれを共有しました。

したがって、チャレンジプログラムに設定されたターゲットを使用して外部プログラムでmach_vm_allocateを使用する場合、チャレンジプログラムは次のようなものである必要があるだけです。

main=65259;

そのシェルコードはそれ自体への短いジャンプ(無限ジャンプ/ループ)であるため、プログラムは開いたままで、外部プログラムから参照できます。

考えられる解決策2:C(Mac OS X x86_64)、8バイト

おかしなことに、valgrindの出力を見ていると、少なくともvalgrindによると、dyldがメモリをリークしていることがわかりました。したがって、事実上、すべてのプログラムがメモリをリークしています。この場合、実際には何もしない(単に終了する)プログラムを作成することができ、実際にはメモリリークが発生します。

ソース:

main(){}


==55263== LEAK SUMMARY:
==55263==    definitely lost: 696 bytes in 17 blocks
==55263==    indirectly lost: 17,722 bytes in 128 blocks
==55263==      possibly lost: 0 bytes in 0 blocks
==55263==    still reachable: 0 bytes in 0 blocks
==55263==         suppressed: 16,316 bytes in 272 blocks

2

平易な英語71 70 58 35バイト

空白行を削除して1バイトを削除しました。「bogon」タイプの定義を削除し、「bogon」サブタイプの代わりに親の「thing」タイプを使用して、12バイトを削除しました。完全なプログラムからメモリをリークするルーチンに切り替えることで23バイトを削除しました。

ゴルフバージョン:

To x:
Allocate memory for a thing.

完全なプログラムであり、サブタイプ定義を使用し、メモリリークを起こさないゴルフされていないバージョン:

A bogon is a thing.

To do something:
  Allocate memory for a bogon.
  Destroy the bogon.

To run:
  Start up.
  Do something.
  Shut down.

「x」のゴルフバージョンが呼び出されると、「x」が呼び出される回数に比例してメモリがリークします。ゴルフバージョンでは、「ものの割り当てを解除します。」メモリリークを修正します。

プレーンイングリッシュはデフォルトでメモリリークをチェックします。メモリをリークするバージョンが実行されると、プログラムがシャットダウンする直前にダイアログボックスが表示されます。ダイアログボックスには、「デバッグ」というタイトル、「1点滴」というメッセージ、および「OK」ボタンがあります。リーク関数が呼び出される回数が多いほど、メッセージ内の「滴り」の数が多くなります。メモリをリークしないバージョンを実行すると、ダイアログボックスは表示されません。

平易な英語では、「もの」は二重にリンクされたリスト内のアイテムへのポインタです。「モノ」、「起動する」、「シャットダウンする」は、「ヌードル」と呼ばれるモジュールで定義され、各プロジェクトに(通常は個別のファイルとして)コピーする必要があります。「A」、「the」、「to」、「to memory」、「to destroy」はコンパイラで定義されています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.