Sua tarefa é escrever um código que vaze pelo menos um byte de memória no menor número possível de bytes. A memória deve ter vazamento e não apenas alocada .
Memória vazada é a memória que o programa aloca, mas perde a capacidade de acessar antes de poder desalocar a memória adequadamente. Para a maioria dos idiomas de alto nível, essa memória deve ser alocada no heap.
Um exemplo em C ++ seria o seguinte programa:
int main(){new int;}
Isso cria um new int
heap sem um ponteiro para ele. Essa memória vaza instantaneamente porque não temos como acessá-la.
Aqui está a aparência de um resumo de vazamento da 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
Muitos idiomas têm um depurador de memória (como o Valgrind ), se você puder incluir a saída desse depurador para confirmar se há memória vazada.
O objetivo é minimizar o número de bytes em sua fonte.
Respostas:
Perl (5.22.2), 0 bytes
Experimente online!
Eu sabia que haveria alguma linguagem por aí que vazaria memória em um programa vazio. Eu esperava que fosse um esolang, mas acontece que
perl
vaza memória em qualquer programa. (Suponho que isso seja intencional, porque liberar memória, se você sabe que vai sair de qualquer maneira, perde tempo; como tal, a recomendação comum hoje em dia é vazar a memória restante assim que você estiver nas rotinas de saída do programa .)Verificação
fonte
perl --version
na máquina , apesar de nunca conseguir executar nenhum programa.C,
48 3122 bytesAviso: não execute isso muitas vezes.
Obrigado a Dennis por muita ajuda / idéias!
Isso vai um passo adiante.
shmget
aloca memória compartilhada que não é desalocada quando o programa termina. Ele usa uma chave para identificar a memória, então usamos um int não inicializado. Esse é um comportamento tecnicamente indefinido, mas praticamente significa que usamos o valor que está logo acima do topo da pilha quando isso é chamado. Isso será gravado na próxima vez que algo for adicionado à pilha, então perderemos a chave.O único caso em que isso não funciona é se você pode descobrir o que estava na pilha antes. Por mais 19 bytes extras, você pode evitar este problema:
Ou, para 26 bytes:
Mas com este, a memória vaza após a saída do programa. Durante a execução, o programa tem acesso à memória que é contrária às regras, mas após o término do programa, perdemos o acesso à chave e a memória ainda está alocada. Isso requer a randomização do layout do espaço de endereço (ASLR), caso contrário
&k
será sempre o mesmo. Atualmente, o ASLR normalmente está ativado por padrão.Verificação:
Você pode usar
ipcs -m
para ver qual memória compartilhada existe no seu sistema. Eu removi entradas pré-existentes para maior clareza:fonte
Unlambda (
c-refcnt/unlambda
), 1 byteExperimente online!
É realmente um desafio encontrar um intérprete pré-existente que vaze memória em programas muito simples. Nesse caso, usei o Unlambda. Há mais de um intérprete oficial da Unlambda, mas
c-refcnt
é um dos mais fáceis de construir, e possui a propriedade útil de vazar memória quando um programa é executado com êxito. Então, tudo o que eu precisava dar aqui era o programa Unlambda legal mais simples possível, um não operacional. (Observe que o programa vazio não funciona aqui; a memória ainda pode ser acessada no momento em que o intérprete falha).Verificação
fonte
TI-Basic, 12 bytes
"... um vazamento de memória é onde você usa Goto / Lbl dentro de um loop ou If condicional (qualquer coisa que possua um comando End) para pular fora dessa estrutura de controle antes que o comando End seja alcançado ..." (mais)
fonte
Pause
no final? Você pode salvar 2 bytes.Python <3.6.5, 23 bytes
property.__init__
vazamentos referências ao da antiga propriedadefget
,fset
,fdel
, e__doc__
se você chamá-lo em um já inicializadaproperty
instância. Esse é um erro, eventualmente relatado como parte do problema 31787 do CPython e corrigido no Python 3.6.5 e Python 3.7.0 . (Além disso, sim,property([])
é algo que você pode fazer.)fonte
C #, 34 bytes
Esta solução não requer o Heap. Ele só precisa de um GC realmente trabalhador ( Garbage Collector ).
Essencialmente, transforma o GC em seu próprio inimigo.
Explicação
Sempre que o destruidor é chamado, ele cria novas instâncias dessa classe maligna, desde que o tempo limite se esgote e diz ao GC para abandonar esse objeto sem esperar que o destruidor termine. Até então, milhares de novas instâncias foram criadas.
A "maldade" disso é que, quanto mais o GC está trabalhando, mais isso vai explodir na sua cara.
Isenção de responsabilidade : seu GC pode ser mais inteligente que o meu. Outras circunstâncias no programa podem fazer com que o GC ignore o primeiro objeto ou seu destruidor. Nesses casos, isso não explodirá. Mas em muitas variações será . A adição de alguns bytes aqui e ali pode garantir um vazamento para todas as circunstâncias possíveis. Bem, exceto pelo interruptor, talvez.
Teste
Aqui está uma suíte de testes :
Saída após 10 minutos:
São 2 684 476 624 bytes. O total
WorkingSet
do processo foi de cerca de 4,8 GBEsta resposta foi inspirada no maravilhoso artigo de Eric Lippert: Quando tudo que você sabe está errado .
fonte
class L{~L(){new L();}}
? AFAIK é ofor(;;)
único que faz vazar memória mais rapidamente, certo?C (gcc) , 15 bytes
Verificação
fonte
Javascript, 14 bytes
Golfe
Registra um manipulador de intervalo vazio com um atraso padrão, descartando o ID do timer resultante (impossibilitando o cancelamento).
Eu usei um intervalo não padrão, para criar vários milhões de temporizadores, para ilustrar o vazamento, pois o uso de um intervalo padrão consome a CPU como um louco.
fonte
if(window && window.setInterval && typeof window.setInterval === 'function') { window.setInterval(0); }
clearInterval
com um ID de incremento até que o intervalo se esgote. Por exemplo:for(let i=0;i<1e5;i++){try{clearInterval(i);}catch(ex){}}
free()
Java, 10 bytes
Finalmente, uma resposta competitiva em Java!
Golfe
Esta é uma referência de método (contra uma constante de cadeia), que pode ser usada assim:
Uma string literal
". "
será automaticamente adicionado ao global internado piscina cordas, como sustenta ajava.lang.String
classe, e como nós immediatelly prepará-la, a referência a ele não podem ser reutilizados mais no código (a menos que você declarar exatamente a mesma seqüência novamente).https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#intern--
Você pode transformar isso em um vazamento de memória "grau de produção", adicionando a sequência a si mesma e, em seguida, invocando o método intern () explicitamente, em um loop.
fonte
("." + " ").intern()
que faria (se eles fossem dados do usuário ou não, por isso desconsideramos as otimizações do compilador).simply by guessing it correctly
, mas isso não significa que não exista um vazamento de memória.there's probably some way to use reflection to determine the string's contents too
você poderia demonstrar isso? (dica, String.intern () é implementada no código nativo ).Ferrugem, 52 bytes
Aloca alguns bytes com o sistema malloc. Isso pressupõe que o ABI errado seja aceitável.
Ferrugem (em teoria), 38 bytesAlocamos memória na pilha, extraímos um ponteiro bruto e depois a ignoramos, vazando efetivamente. (
Box::into_raw
é mais curto entãostd::mem::forget
).No entanto, o Rust, por padrão, usa jemalloc, que o valgrind não pode detectar nenhum vazamento . Poderíamos mudar para o alocador de sistema, mas isso adiciona 50 bytes e requer todas as noites. Muito obrigado pela segurança da memória.
Saída do primeiro programa:
fonte
8086 ASM, 3 bytes
Este exemplo pressupõe que um tempo de execução C esteja vinculado.
isso monta para
e9 XX XX
ondeXX XX
está o endereço relativo de_malloc
Isso chama
malloc
para alocar uma quantidade imprevisível de memória e, em seguida, retorna imediatamente, encerrando os processos. Em alguns sistemas operacionais como o DOS, a memória pode não ser recuperada até que o sistema seja reiniciado!fonte
Quarto, 6 bytes
Golfe
Aloca uma string vazia com
s" "
, deixando o endereço e o comprimento (0) na pilha e depois os multiplica (resultando na perda de um endereço de memória).Valgrind
fonte
vá 45 bytes
isso cria uma goroutine anônima com um loop infinito dentro dela. o programa pode continuar funcionando normalmente, pois iniciar a goroutine é como gerar um thread pequeno em execução simultânea, mas o programa não tem como recuperar a memória que foi alocada para a goroutine. o coletor de lixo nunca o coletará, pois ainda está em execução. algumas pessoas chamam isso de 'vazar uma goroutine'
fonte
C.malloc(8)
, já que você precisaimport"C"
Java 1.3, 23 bytes
Criando um encadeamento, mas não iniciando-o. O encadeamento é registrado no pool de encadeamentos interno, mas nunca será iniciado, portanto, nunca será encerrado e, portanto, nunca será candidato ao GC. É um objeto irrecuperável, preso nos limbos do Java.
É um bug no Java até a versão 1.3 incluída , pois foi corrigida posteriormente.
Testando
O programa a seguir certifica-se de poluir a memória com novos objetos de encadeamento e mostra um espaço de memória livre decrescente. Para fins de teste de vazamentos, intensamente faço o GC funcionar.
fonte
Befunge ( fungos ), 1 byte
Isso pode depender da plataforma e da versão (eu testei apenas com a versão 1.0.4 no Windows), mas os fungos historicamente têm sido um intérprete muito vazado. O
$
comando (drop) não deve fazer nada em uma pilha vazia, mas repetir esse código de alguma forma consegue vazar muita memória muito rapidamente. Em questão de segundos, ele esgotou alguns shows e trava com um erro de "falta de memória".Observe que ele não precisa necessariamente ser um
$
comando - praticamente qualquer coisa faria. Porém, ele não funcionará com um arquivo de origem em branco. Tem que haver pelo menos uma operação.fonte
Swift 3, 38 bytes
Nova versão:
x
tem uma forte referência a si próprio, para que não seja desalocado, levando a um vazamento de memória.Versão antiga:
x
contém uma forte referênciay
e vice-versa. Assim, nenhum deles será desalocado, levando a um vazamento de memória.fonte
x
ey
, portanto, isso realmente não parece um vazamento para mim (a menos que você os destrua de alguma forma).do
bloco que resolveria o problema que o zeppelin levantou, certo?do
funcionaria também. Boa ideia!class X{var x: X!};do{let x=X();x.x=x}
Delphi (Object Pascal) - 33 bytes
Criando um objeto sem um programa de console completo variável:
A ativação do FastMM4 no projeto mostrará o vazamento de memória:
fonte
C # - 84 bytes
Isso aloca exatamente 1 byte de memória não gerenciada e perde a
IntPtr
, que acredito ser a única maneira de obter ou liberá-la. Você pode testá-lo colocando-o em um loop e aguardando a falha do aplicativo (pode querer adicionar alguns zeros para acelerar as coisas).Eu considerei
System.IO.File.Create("a");
e tal, mas eu não estou convencido de que estes são, necessariamente, vazamentos de memória, como o próprio aplicativo irá coletar a memória, é o OS embaixo que pode vazar (porqueClose
ouDispose
não foram chamados). O acesso a arquivos também requer permissões do sistema de arquivos e ninguém deseja confiar nelas. E, de qualquer forma, isso não vazará, porque não há nada que impeça a chamada do finalizador (o que liberta os recursos subjacentes é possível), que a estrutura inclui para atenuar esses tipos de erros de julgamento (até certo ponto) e confundir programadores com bloqueio de arquivos aparentemente não determinístico (se você é um cínico). Agradeço a Jon Hanna por me esclarecer isso.Estou um pouco decepcionado por não encontrar um caminho mais curto. O .NET GC funciona, não consigo pensar em nada
IDisposables
no mscorlib que vazará definitivamente (e, de fato, todos parecem ter finalizadores, que chato) , não conheço outra maneira de alocar memória não gerenciada (com falta de PInvoke ), e a reflexão garante que qualquer coisa com uma referência a ele (independentemente da semântica do idioma (por exemplo, membros privados ou classes sem acessadores)) possa ser encontrada.fonte
System.IO.File.Create("a")
não vai vazar nada, masGC.SuppressFinalize(System.IO.File.Create("a"))
vai, como é explicitamente solicitado a não executar o finalizador doFileStream
produzido.<!-- language: lang-c# -->
Obrigado por esta e boa resposta! (É C #, então eu amo isso)Fator , 13 bytes
O fator possui gerenciamento automático de memória, mas também fornece acesso a algumas funcionalidades da libc:
Aloca manualmente 1 byte de memória, retorna seu endereço e o elimina.
malloc
na verdade, registra uma cópia para rastrear vazamentos de memória e liberar duas vezes, mas identificar o que você vazou não é uma tarefa fácil.Se você preferir se certificar de que realmente perde essa referência:
O teste de vazamentos
[ 1 malloc drop ] leaks.
diz:O teste de vazamentos
[ 1 (malloc) drop ] leaks.
diz:Ah não! Pobre fator, ele tem Alzheimer agora! D:
fonte
AutoIt , 39 bytes
Aloca um byte do heap. Como o identificador retornado por
_MemGlobalAlloc
é descartado, não há como liberar explicitamente essa alocação.fonte
Lisp comum (apenas SBCL),
28.26 bytesVocê executa assim
sbcl --eval 'sb-alien::(make-alien int)'
:; nada é impresso nem retornado, mas a alocação de memória acontece. Se eu envolver o formulário dentro de a(print ...)
, o ponteiro será exibido no REPL.package::(form)
é uma notação especial no SBCL para vincular temporariamente o pacote atual ao ler um formulário. Isso é usado aqui para evitar prefixar ambosmake-alien
eint
comsb-alien
. Eu acho que seria trapaça assumir que o pacote atual está definido para este, porque esse não é o caso na inicialização.make-alien
aloca memória para um determinado tipo e um tamanho opcional (usando malloc).Ao executar isso no REPL, adicione
0
após a alocação para que o REPL não retorne o ponteiro, mas esse valor. Caso contrário, que sem ser uma verdadeira fuga porque o REPL se lembra dos últimos três valores devolvidos (Veja*
,**
,***
) e nós ainda poderia ter uma chance de liberar a memória alocada.2 bytes removidos graças a PrzemysławP, obrigado!
fonte
1
(ou2
,3
etc.) em vez de()
retornar valor1
? Isso economizaria 1 byte. Também esta resposta é apenas REPL? Talvez se você carregar código comload
você não pode incluir()
ou qualquer coisa no final, porque ele não estará acessível de qualquer maneira?eval
e isso funciona como você disse. Muito obrigado!C ++, 16 bytes
Não tenho o valgrind para verificar se há vazamentos, mas com certeza deveria.Caso contrário, eu tentaria:Resultado Valgrind
(Ele realmente vaza)
fonte
g++ 4.3.2
(não o mais recente) e compila muito bem. Nenhum tipo de retorno éint
por padrão, eu acho. Com-Wall
eu tenho um aviso:plop.cpp:1: warning: ISO C++ forbids declaration of 'main' with no type
[]{new int;}
como uma função C ++ (o desafio não especificou um programa inteiro).Java (OpenJDK 9) ,
322220 bytesExperimente online!
Este é outro vazamento de memória que não usa o cache de strings. Aloca metade da sua RAM e você não pode fazer nada com ela.
Obrigado ao zeppelin por salvar todos os bytes
fonte
Unsafe
exemplo da variável estática dentro dele, assim: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
por um inicializador estáticostatic{try{}catch(Exception e){}}
(que pode ser um pouco mais difícil de iniciar, mas é válido e compilável).a
vez deargs
e remova o público. tio.run/nexus/…c, 9 bytes
Prova:
fonte
gcc
é. Isso também deve funcionar com o programa vazio. Tentegcc src.c && valgrind ./a.out
, o que deve produzir um resultado limpo.C #, 109 bytes
Descobrimos a idéia por trás desse vazamento no código de produção e pesquisá-lo leva a este artigo. O principal problema está nesta longa citação do artigo (leia-o para obter mais informações):
A execução do compilador no Visual Studio 2015 e a janela Ferramentas de diagnóstico mostra os seguintes resultados após cerca de 38 segundos. Observe que a memória do processo está subindo constantemente e o Garbage Collector (GC) continua em execução, mas não pode coletar nada.
fonte
C 30 bytes
Resultados de Valgrind:
fonte
main(){malloc(1);}
?Dardo, 76 bytes
Um pouco como a resposta JavaScript. Quando você chama
.listen
um objeto de fluxo Dart, recebe de volta um StreamSubscription, que permite desconectar-se do fluxo. No entanto, se você jogar fora isso, nunca poderá cancelar a inscrição no fluxo, causando um vazamento. A única maneira de corrigir o vazamento é se o próprio Stream for coletado, mas ele ainda é referenciado internamente por um combo StreamController + Timer.Infelizmente, o Dart é inteligente demais para as outras coisas que tentei.
()async=>await new Completer().future
não funciona porque usar aguardar é o mesmo que fazernew Completer().future.then(<continuation>)
, o que permite que o fechamento seja destruído no segundo Completer não é referenciado (o Completer mantém uma referência ao futuro de.future
, o Future mantém uma referência à continuação como um fechamento).Além disso, os Isolados (também conhecidos como threads) são limpos pelo GC, portanto, gerar um novo thread e interrompê-lo imediatamente (
import'dart:isolate';main(_)=>Isolate.spawn(main,0,paused:true);
) não funciona. Mesmo gerando um Isolate com um loop infinito (import'dart:isolate';f(_){while(true){print('x');}}main()=>Isolate.spawn(f,0);
) mata o Isolate e sai do programa.Ah bem.
fonte
Rápido, 12 bytes
Explicação:
Esse é um vazamento de memória de fato que pode ocorrer em qualquer idioma, independentemente de o idioma usar gerenciamento manual de memória, contagem automática de referência (ARC, como Swift) ou até mesmo coleta de lixo abrangente.
[3,5]
é apenas uma matriz literal. Essa matriz aloca memória suficiente para pelo menos esses dois elementos. O3
e5
são apenas arbitrários.Subscrever (indexar) um
Array<T>
produz umArraySlice<T>
. AnArraySlice<T>
é uma visão na memória da matriz da qual ela foi criada.[3,5][0...0]
produz umArraySlice<Int>
, cujo valor é[3]
. Observe que3
nesta fatia é o mesmo3
elemento que3
o originalArray
mostrado acima, não uma cópia.A fatia resultante pode ser armazenada em uma variável e usada. A matriz original não é mais referenciada; portanto, você poderia pensar que poderia ser desalocada. No entanto, não pode.
Como a fatia expõe uma exibição na memória da matriz de onde veio, a matriz original deve ser mantida viva enquanto a fatia permanecer. Portanto, dos
2
tamanhos de elementos originais de memória que foram alocados, apenas o primeiro tamanho de elemento de memória está sendo usado, sendo necessário que o outro exista para não alocar o primeiro. O segundo tamanho do elemento da memória é de fator vazado.A solução para esse problema é não manter vivas pequenas fatias de matrizes grandes por muito tempo. Se você precisar persistir o conteúdo da fatia, promova-o para uma matriz, que acionará a memória a ser copiada, removendo a dependência da memória da matriz original:
fonte
Solução 1: C (Mac OS X x86_64), 109 bytes
A fonte do golf_sol1.c
O programa acima precisa ser compilado com acesso de execução no segmento __DATA.
Em seguida, para executar o programa, execute o seguinte:
Resultados:
Infelizmente, o Valgrind não observa a memória alocada nas chamadas do sistema, portanto, não consigo mostrar um vazamento detectado.
No entanto, podemos ver o vmmap para ver a grande parte da memória alocada (metadados MALLOC).
Explicação
Então, acho que preciso descrever o que realmente está acontecendo aqui, antes de avançar para a solução aprimorada.
Esta função principal está abusando da declaração de tipo ausente de C (portanto, o padrão é int, sem que seja necessário desperdiçar caracteres para escrevê-la), bem como o funcionamento dos símbolos. O vinculador se preocupa apenas com encontrar um símbolo chamado
main
para chamar. Então, aqui estamos fazendo principal uma matriz de int que estamos inicializando com nosso código de shell que será executado. Por isso, main não será adicionado ao segmento __TEXT, mas ao segmento __DATA, razão pela qual precisamos compilar o programa com um segmento __DATA executável.O shellcode encontrado em main é o seguinte:
O que isso está fazendo é chamar a função syscall para alocar uma página de memória (o syscall mach_vm_allocate usa internamente). RAX deve ser igual a 0x100000a (informa ao syscall qual função queremos), enquanto o RDI mantém o destino da alocação (no nosso caso, queremos que seja mach_task_self ()), o RSI deve manter o endereço para gravar o ponteiro na memória recém-criada (portanto, estamos apenas apontando para uma seção da pilha), RDX mantém o tamanho da alocação (estamos passando RAX ou 0x100000a apenas para economizar em bytes), R10 mantém os sinalizadores (estamos indicando que pode seja alocado em qualquer lugar).
Agora não é óbvio de onde RAX e RDI estão obtendo seus valores. Sabemos que o RAX precisa ser 0x100000a e o RDI precisa ser o valor que mach_task_self () retorna. Felizmente, mach_task_self () é na verdade uma macro para uma variável (mach_task_self_), que está no mesmo endereço de memória todas as vezes (no entanto, deve mudar na reinicialização). Na minha instância específica, mach_task_self_ está localizado em 0x00007fff7d578244. Portanto, para reduzir as instruções, passaremos esses dados do argv. É por isso que rodamos o programa com esta expressão
$(ruby -e 'puts "\xf5\xff\xff\xfe\xff\xff\x44\x82\x57\x7d\xff\x7f"')
para o primeiro argumento. A string é os dois valores combinados, em que o valor RAX (0x100000a) é de apenas 32 bits e teve um complemento aplicado a ela (portanto, não há bytes nulos; apenas NÃO é o valor para obter o original), o próximo valor é o RDI (0x00007fff7d578244) que foi deslocado para a esquerda com 2 bytes extras de lixo eletrônico adicionados ao final (novamente para excluir os bytes nulos, basta voltar à direita para voltar ao original).Após o syscall, estamos gravando em nossa memória recém-alocada. A razão para isso é porque a memória alocada usando mach_vm_allocate (ou este syscall) é na verdade páginas da VM e não é automaticamente paginada na memória. Em vez disso, eles são reservados até que os dados sejam gravados neles e, em seguida, essas páginas são mapeadas na memória. Não tinha certeza se atenderia aos requisitos se fosse reservado apenas.
Para a próxima solução, aproveitaremos o fato de que nosso código de shell não possui bytes nulos e, portanto, podemos movê-lo para fora do código de nosso programa para reduzir o tamanho.
Solução 2: C (Mac OS X x86_64), 44 bytes
A fonte para golf_sol2.c
O programa acima precisa ser compilado com acesso de execução no segmento __DATA.
Em seguida, para executar o programa, execute o seguinte:
O resultado deve ser o mesmo de antes, pois estamos fazendo uma alocação do mesmo tamanho.
Explicação
Segue o mesmo conceito da solução 1, com a exceção de que movemos a parte do nosso código de vazamento para fora do programa.
O shellcode encontrado em main agora é o seguinte:
Isso basicamente copia o código de shell que passamos no argv para estar após esse código (então, depois de copiado, ele executará o código de shell inserido). O que funciona a nosso favor é que o segmento __DATA terá pelo menos um tamanho de página; portanto, mesmo que nosso código não seja tão grande, ainda podemos escrever com mais segurança. A desvantagem é a solução ideal aqui, nem precisaria da cópia; em vez disso, basta chamar e executar o código de shell diretamente no argv. Mas, infelizmente, essa memória não tem direitos de execução. Poderíamos alterar os direitos dessa memória, no entanto, exigiria mais código do que simplesmente copiá-lo. Uma estratégia alternativa seria alterar os direitos de um programa externo (mas mais sobre isso posteriormente).
O código de shell que passamos para o argv é o seguinte:
É o mesmo que o nosso código anterior, a única diferença é que estamos incluindo os valores para EAX e RDI diretamente.
Solução possível 1: C (Mac OS X x86_64), 11 bytes
A idéia de modificar o programa externamente, nos dá a possível solução de mover o vazador para um programa externo. Onde nosso programa atual (envio) é apenas um programa fictício, e o programa vazador alocará um pouco de memória em nosso programa de destino. Agora eu não tinha certeza se isso se enquadrava nas regras para esse desafio, mas mesmo assim é compartilhado.
Portanto, se usássemos mach_vm_allocate em um programa externo com a meta definida para o nosso programa de desafios, isso poderia significar que nosso programa de desafios precisaria ser algo como:
Onde esse código de shell é simplesmente um pequeno salto para si mesmo (salto / loop infinito), o programa permanece aberto e podemos fazer referência a um programa externo.
Solução possível 2: C (Mac OS X x86_64), 8 bytes
Curiosamente, quando eu estava olhando para a saída do valgrind, vi que, pelo menos de acordo com o valgrind, o dyld vazava memória. Tão eficazmente que todo programa está vazando alguma memória. Sendo esse o caso, poderíamos realmente criar um programa que não faz nada (simplesmente sai) e que realmente estará vazando memória.
Fonte:
fonte
Inglês simples ,
71705835 bytesRemovido 1 byte excluindo uma linha em branco. Foram removidos 12 bytes, eliminando a definição de tipo "bogon" e usando o tipo "coisa" pai em vez do subtipo "bogon". Foram removidos 23 bytes passando de um programa completo para apenas uma rotina que vaza memória.
Versão Golfed:
Versão não destruída que é um programa completo, usa uma definição de subtipo e não vaza memória:
Se a versão em golf de "x" for chamada, ela vazará memória proporcionalmente ao número de vezes que "x" for chamada. Na versão para golfe, "Desaloque a coisa". corrigiria o vazamento de memória.
Por padrão, o inglês comum verifica vazamentos de memória. Quando a versão que vaza memória é executada, uma caixa de diálogo será exibida antes do encerramento do programa. A caixa de diálogo tem um título de "depuração", uma mensagem de "1 gotejamento" e um botão "OK". Quanto mais vezes a função de vazamento é chamada, maior o número de "gotas" na mensagem. Quando a versão que não vaza memória é executada, a caixa de diálogo não aparece.
Em inglês simples, uma "coisa" é um ponteiro para um item em uma lista duplamente vinculada. "Coisa", "iniciar" e "desligar" são definidas em um módulo chamado "o macarrão", que precisa ser copiado (geralmente como um arquivo separado) em cada projeto. "A", "o", "para", "alocar memória" e "destruir" são definidos no compilador.
fonte