{"id":617,"date":"2024-09-16T11:47:00","date_gmt":"2024-09-16T14:47:00","guid":{"rendered":"https:\/\/suspensao.blog.br\/descrenca\/?p=617"},"modified":"2025-03-17T18:21:13","modified_gmt":"2025-03-17T21:21:13","slug":"implementando-malloc-e-free-memoria-antiga-tem-preferencia","status":"publish","type":"post","link":"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-memoria-antiga-tem-preferencia\/","title":{"rendered":"Implementando malloc() e free() \u2014 mem\u00f3ria antiga tem prefer\u00eancia"},"content":{"rendered":"\n<p>No <a href=\"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-reduzindo-ainda-mais-o-heap\/\"><em>post<\/em> anterior<\/a> desta s\u00e9rie sobre a implementa\u00e7\u00e3o das fun\u00e7\u00f5es <code>malloc()<\/code> e <code>free()<\/code>, mostramos como \u00e9 poss\u00edvel reutilizar blocos de mem\u00f3ria e reduzir o <em>heap<\/em> ao liberar os blocos mais novos. No entanto, a fun\u00e7\u00e3o atual reutiliza o bloco de mem\u00f3ria livre mais recente, levando a um consumo de mem\u00f3ria maior. Vamos analisar como isso ocorre.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Redu\u00e7\u00e3o do <em>heap<\/em> com reaproveitamento de blocos recentes<\/h3>\n\n\n\n<p>Considere o cen\u00e1rio a seguir. Primeiro, alocamos quatro blocos de mem\u00f3ria:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">void *ptr1 = abmalloc(8);<br>void *ptr2 = abmalloc(8);<br>void *ptr3 = abmalloc(8);<br>void *ptr4 = abmalloc(8); <\/pre>\n\n\n\n<p>A estrutura em mem\u00f3ria pode ser visualizada assim:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><a href=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-inicial-atual.svg\"><img loading=\"lazy\" decoding=\"async\" width=\"16916\" height=\"1204\" data-attachment-id=\"646\" data-permalink=\"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-memoria-antiga-tem-preferencia\/lista-inicial-atual\/\" data-orig-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-inicial-atual.svg\" data-orig-size=\"16916,1204\" data-comments-opened=\"1\" data-image-meta=\"[]\" data-image-title=\"lista-inicial-atual\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-inicial-atual.svg\" data-large-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-inicial-atual.svg\" src=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-inicial-atual.svg\" alt=\"Lista ligada com quatro n\u00f3s. Os n\u00f3s mais novos apontam para os mais antigos. Todos os n\u00f3s est\u00e3o em uso, por isso todos est\u00e3o com o r\u00f3tulo Ocupado.\" class=\"wp-image-646\" style=\"width:auto;height:50px\"\/><\/a><\/figure>\n<\/div>\n\n\n<p>Agora, liberamos o primeiro e o terceiro bloco&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">abfree(ptr1);<br>abfree(ptr3); <\/pre>\n\n\n\n<p>&#8230;resultando na seguinte estrutura:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-medium\"><a href=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-liberada-atual-1.svg\"><img loading=\"lazy\" decoding=\"async\" width=\"16916\" height=\"1204\" data-attachment-id=\"648\" data-permalink=\"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-memoria-antiga-tem-preferencia\/lista-liberada-atual-1\/\" data-orig-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-liberada-atual-1.svg\" data-orig-size=\"16916,1204\" data-comments-opened=\"1\" data-image-meta=\"[]\" data-image-title=\"lista-liberada-atual-1\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-liberada-atual-1.svg\" data-large-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-liberada-atual-1.svg\" src=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-liberada-atual-1.svg\" alt=\"Lista ligada com quatro n\u00f3s. Os n\u00f3s mais novos apontam para os mais antigos. O segundo e quarto n\u00f3s da lista (ou seja, o segundo mais novo e o mais antigo de todos) foram liberados com free(), ent\u00e3o est\u00e3o rotulados com a palavra Livre.\" class=\"wp-image-648\"\/><\/a><\/figure>\n<\/div>\n\n\n<p>Em seguida, alocamos outro bloco do mesmo tamanho:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">void *ptr5 = abmalloc(8); <\/pre>\n\n\n\n<p>Como fun\u00e7\u00e3o <code>abmalloc()<\/code> come\u00e7a a busca pelo bloco livre mais recente, ela reutiliza o bloco que est\u00e1 no topo. Se agora liberarmos o \u00faltimo bloco:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-realocada-atual.svg\"><img loading=\"lazy\" decoding=\"async\" width=\"16916\" height=\"1204\" data-attachment-id=\"649\" data-permalink=\"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-memoria-antiga-tem-preferencia\/lista-realocada-atual\/\" data-orig-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-realocada-atual.svg\" data-orig-size=\"16916,1204\" data-comments-opened=\"1\" data-image-meta=\"[]\" data-image-title=\"lista-realocada-atual\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-realocada-atual.svg\" data-large-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-realocada-atual.svg\" src=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-realocada-atual.svg\" alt=\"Lista ligada com quatro n\u00f3s. Os n\u00f3s mais novos apontam para os mais antigos. Agora apenas o \u00faltimo n\u00f3 est\u00e1 liberado e rotulado com a palavra Livre\" class=\"wp-image-649\"\/><\/a><\/figure>\n<\/div>\n\n\n<p>Se, agora, liberamos o \u00faltimo bloco&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">abfree(ptr4);<\/pre>\n\n\n\n<p>&#8230;poderemos reduzir o tamanho do <em>heap<\/em> em apenas um bloco de 8 bytes, j\u00e1 que o pen\u00faltimo bloco n\u00e3o est\u00e1 mais livre:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-heap-reduzido-atual.svg\"><img loading=\"lazy\" decoding=\"async\" width=\"12550\" height=\"1204\" data-attachment-id=\"650\" data-permalink=\"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-memoria-antiga-tem-preferencia\/lista-heap-reduzido-atual\/\" data-orig-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-heap-reduzido-atual.svg\" data-orig-size=\"12550,1204\" data-comments-opened=\"1\" data-image-meta=\"[]\" data-image-title=\"lista-heap-reduzido-atual\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-heap-reduzido-atual.svg\" data-large-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-heap-reduzido-atual.svg\" src=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-heap-reduzido-atual.svg\" alt=\"Lista ligada com tr\u00eas n\u00f3s. Os n\u00f3s mais novos apontam para os mais antigos. O \u00faltimo n\u00f3 est\u00e1 liberado e rotulado com a palavra Livre\" class=\"wp-image-650\"\/><\/a><\/figure>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\">Reaproveitamento de blocos antigos<\/h3>\n\n\n\n<p>Agora, imagine o mesmo cen\u00e1rio, mas com uma modifica\u00e7\u00e3o: nossa fun\u00e7\u00e3o busca blocos livres come\u00e7ando pelo mais antigo.<\/p>\n\n\n\n<p>A estrutura inicial ser\u00e1 a mesma&#8230;<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-inicial-desejada.svg\"><img loading=\"lazy\" decoding=\"async\" width=\"17116\" height=\"1204\" data-attachment-id=\"651\" data-permalink=\"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-memoria-antiga-tem-preferencia\/lista-inicial-desejada\/\" data-orig-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-inicial-desejada.svg\" data-orig-size=\"17116,1204\" data-comments-opened=\"1\" data-image-meta=\"[]\" data-image-title=\"lista-inicial-desejada\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-inicial-desejada.svg\" data-large-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-inicial-desejada.svg\" src=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-inicial-desejada.svg\" alt=\"Lista ligada com quatro n\u00f3s. Os n\u00f3s mais antigos apontam para os mais novos. Todos os n\u00f3s est\u00e3o em uso e rotulados com a palavra Ocupado.\" class=\"wp-image-651\"\/><\/a><\/figure>\n<\/div>\n\n\n<p>&#8230;e novamente liberamos o primeiro e o terceiro bloco de mem\u00f3ria:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-liberada-desejada.svg\"><img loading=\"lazy\" decoding=\"async\" width=\"16950\" height=\"1205\" data-attachment-id=\"652\" data-permalink=\"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-memoria-antiga-tem-preferencia\/lista-liberada-desejada\/\" data-orig-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-liberada-desejada.svg\" data-orig-size=\"16950,1205\" data-comments-opened=\"1\" data-image-meta=\"[]\" data-image-title=\"lista-liberada-desejada\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-liberada-desejada.svg\" data-large-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-liberada-desejada.svg\" src=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-liberada-desejada.svg\" alt=\"Lista ligada com quatro n\u00f3s. Os n\u00f3s mais antigos apontam para os mais novos. O primeiro e terceiro n\u00f3s (isto \u00e9, o mais antigo e o terceiro mais antigo\/segundo mais novo) foram desalocados e est\u00e3o rotulados com a palavra Livre\" class=\"wp-image-652\"\/><\/a><\/figure>\n<\/div>\n\n\n<p>Dessa vez, o primeiro bloco ser\u00e1 reutilizado:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-realocada-desejada.svg\"><img loading=\"lazy\" decoding=\"async\" width=\"16971\" height=\"1205\" data-attachment-id=\"653\" data-permalink=\"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-memoria-antiga-tem-preferencia\/lista-realocada-desejada\/\" data-orig-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-realocada-desejada.svg\" data-orig-size=\"16971,1205\" data-comments-opened=\"1\" data-image-meta=\"[]\" data-image-title=\"lista-realocada-desejada\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-realocada-desejada.svg\" data-large-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-realocada-desejada.svg\" src=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-realocada-desejada.svg\" alt=\"Lista ligada com quatro n\u00f3s. Os n\u00f3s mais antigos apontam para os mais novos. O terceiro n\u00f3s (isto \u00e9, o mais antigo e o terceiro mais antigo\/segundo mais novo) foi desalocado. Por isso, est\u00e1 rotulado com a palavra Livre\" class=\"wp-image-653\"\/><\/a><\/figure>\n<\/div>\n\n\n<p>Agora, ao liberarmos o \u00faltimo bloco, teremos dois blocos livres no topo, permitindo reduzir o <em>heap<\/em> em dois blocos de 8 bytes:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><a href=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-heap-reduzido-desejada.svg\"><img loading=\"lazy\" decoding=\"async\" width=\"8271\" height=\"1205\" data-attachment-id=\"654\" data-permalink=\"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-memoria-antiga-tem-preferencia\/lista-heap-reduzido-desejada\/\" data-orig-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-heap-reduzido-desejada.svg\" data-orig-size=\"8271,1205\" data-comments-opened=\"1\" data-image-meta=\"[]\" data-image-title=\"lista-heap-reduzido-desejada\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-heap-reduzido-desejada.svg\" data-large-file=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-heap-reduzido-desejada.svg\" src=\"https:\/\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/05\/lista-heap-reduzido-desejada.svg\" alt=\"Lista ligada com dois n\u00f3s.  Todos est\u00e3o ocupados porque os n\u00f3s livres estavam no topo do heap e, portanto, foram destru\u00eddos.\" class=\"wp-image-654\"\/><\/a><\/figure>\n<\/div>\n\n\n<p>Esse exemplo ilustra como, ao dar prefer\u00eancia a blocos mais novos, acabamos acumulando blocos livres antigos, desperdi\u00e7ando mem\u00f3ria e levando a um crescimento desnecess\u00e1rio do <em>heap<\/em>. A solu\u00e7\u00e3o \u00e9 modificar a estrat\u00e9gia de busca, priorizando a reutiliza\u00e7\u00e3o de blocos mais antigos.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Implementando prefer\u00eancia por blocos antigos<\/h3>\n\n\n\n<p>Para resolver esse problema, vamos implementar uma nova abordagem no c\u00f3digo. Primeiramente, vamos adicionar ao cabe\u00e7alho dos blocos um ponteiro para o pr\u00f3ximo bloco, permitindo percorrermos a mem\u00f3ria de maneira eficiente. Tamb\u00e9m adicionaremos um ponteiro para o primeiro bloco, o que facilitar\u00e1 a busca:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">typedef struct Header {<br>  struct Header *previous, *next;<br>  size_t size;<br>  bool available;<br>} Header;<br><br>Header *first = NULL;<br>Header *last = NULL;<\/pre>\n\n\n\n<p>Agora, faremos uma pequena refatora\u00e7\u00e3o. Como criamos blocos de mem\u00f3ria com headers em duas situa\u00e7\u00f5es diferentes, extrairemos essa l\u00f3gica para uma fun\u00e7\u00e3o auxiliar que aloca e inicializa o cabe\u00e7alho (inclusive setando o campo <code>next<\/code> com <code>NULL<\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Header *header_new(Header *previous, size_t size, bool available) {<br>  Header *header = sbrk(sizeof(Header) + size);<br>  header-&gt;previous = previous;<br>  header-&gt;next = NULL;<br>  header-&gt;size = size;<br>  header-&gt;available = false;<br>  return header;<br>}<\/pre>\n\n\n\n<p>Com essa nova fun\u00e7\u00e3o, podemos simplificar a l\u00f3gica dentro de <code>abmalloc()<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">void *abmalloc(size_t size) {<br>  if (size == 0) {<br>    return NULL;<br>  }<br>  Header *header = last;<br>  while (header != NULL) {<br>    if (header-&gt;available &amp;&amp; (header-&gt;size &gt;= size)) {<br>      header-&gt;available = false;<br>      return header + 1;<br>    }<br>    header = header-&gt;previous;<br>  }<br>  last = header_new(last, size, false);<br>  return last + 1;<br>}<\/pre>\n\n\n\n<p>Agora temos acesso ao primeiro e \u00faltimo blocos e, dado um bloco, podemos descobrir o anterior e o posterior. Sabemos, tamb\u00e9m, que quando o ponteiro para o primeiro bloco for nulo, nenhum bloco ter\u00e1 sido alocado ainda. Ent\u00e3o, neste caso, alocaremos o bloco imediatamente, e inicializaremos tanto first quanto last:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">void *abmalloc(size_t size) {<br>  if (size == 0) {<br>    return NULL;<br>  }<br>  if (first == NULL) {<br>    first = last = header_new(NULL, size, false);<br>    return first + 1;<br>  }<\/pre>\n\n\n\n<p>Se <code>first<\/code> n\u00e3o \u00e9 mais <code>NULL<\/code>, j\u00e1 existem blocos alocados, ent\u00e3o come\u00e7aremos a busca por um bloco reutiliz\u00e1vel. Continuaremos utilizando a vari\u00e1vel <code>header<\/code> como iterador, mas, em vez de come\u00e7ar pelo bloco mais recente, a pesquisa ser\u00e1 iniciada a partir do mais antigo:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  Header *header = first;<\/pre>\n\n\n\n<p>A cada itera\u00e7\u00e3o, avan\u00e7aremos para o pr\u00f3ximo bloco na sequ\u00eancia, em vez de retroceder para o bloco anterior:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  while (header != NULL) {<br>    if (header-&gt;available &amp;&amp; (header-&gt;size &gt;= size)) {<br>      header-&gt;available = false;<br>      return header + 1;<br>    }<br>    header = header-&gt;next;<br>  }<\/pre>\n\n\n\n<p>A l\u00f3gica permanece a mesma: se encontramos um bloco dispon\u00edvel e de tamanho suficiente, ele \u00e9 retornado. Caso contr\u00e1rio, se nenhum bloco reutiliz\u00e1vel for encontrado ap\u00f3s percorrermos a lista, um novo bloco ser\u00e1 alocado:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  last = header_new(last, size, false);<br><\/pre>\n\n\n\n<p>Agora, precisamos ajustar o bloco que era o \u00faltimo (e que, ap\u00f3s a aloca\u00e7\u00e3o, passa a ser o pen\u00faltimo). Ele apontava para <code>NULL<\/code>, mas agora deve apontar para o novo bloco. Para isso, setamos o campo <code>field<\/code> do block anterior com o novo bloco:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  last-&gt;previous-&gt;next = last;<br>  return last + 1;<br>}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Ajustes na Fun\u00e7\u00e3o <code>abfree()<\/code><\/h3>\n\n\n\n<p>A fun\u00e7\u00e3o <code>abfree()<\/code> mant\u00e9m basicamente a mesma estrutura, mas agora devemos tratar alguns casos de borda. Quando liberamos blocos no topo do <em>heap<\/em>, um novo bloco passa a ser o \u00faltimo, conforme j\u00e1 fazemos neste trecho:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">    last = header-&gt;previous;<br>    brk(header)<\/pre>\n\n\n\n<p>Aqui, o ponteiro <code>header<\/code> referencia o \u00faltimo bloco n\u00e3o nulo e dispon\u00edvel na pilha. Temos dois cen\u00e1rios poss\u00edveis: <\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>no primeiro, o bloco atual possui um bloco anterior, que se tornar\u00e1 o novo \u00faltimo bloco. Nesse caso, devemos ajustar o ponteiro <code>next<\/code> desse bloco para <code>NULL<\/code>.<\/li>\n\n\n\n<li>No segundo cen\u00e1rio, o bloco atual n\u00e3o possui um bloco anterior (ou seja, ele \u00e9 o primeiro e mais antigo bloco). Quando ele \u00e9 liberado, a pilha fica vazia. Nesse caso, em vez de tentar atualizar um campo de um bloco inexistente, basta definirmos <code>first<\/code> como <code>NULL<\/code>, indicando que n\u00e3o h\u00e1 mais blocos alocados:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">  last = header-&gt;previous;<br>  if (last != NULL) {<br>    last-&gt;next = NULL;<br>  } else {<br>    first = NULL;<br>  }<br>  brk(header);<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Conclus\u00e3o<\/h3>\n\n\n\n<p>Nossas fun\u00e7\u00f5es <code>abmalloc()<\/code> e <code>abfree()<\/code>  agora est\u00e3o assim:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">typedef struct Header {\n  struct Header *previous, *next;\n  size_t size;\n  bool available;\n} Header;\n\nHeader *first = <span class=\"hljs-keyword\">NULL<\/span>;\nHeader *last = <span class=\"hljs-keyword\">NULL<\/span>;\n\nHeader *header_new(Header *previous, size_t size, bool available) {\n  Header *header = sbrk(sizeof(Header) + size);\n  header-&gt;previous = previous;\n  header-&gt;next = <span class=\"hljs-keyword\">NULL<\/span>;\n  header-&gt;size = size;\n  header-&gt;available = <span class=\"hljs-keyword\">false<\/span>;\n  <span class=\"hljs-keyword\">return<\/span> header;\n}\n\nvoid *abmalloc(size_t size) {\n  <span class=\"hljs-keyword\">if<\/span> (size == <span class=\"hljs-number\">0<\/span>) {\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-keyword\">NULL<\/span>;\n  }\n  <span class=\"hljs-keyword\">if<\/span> (first == <span class=\"hljs-keyword\">NULL<\/span>) {\n    first = last = header_new(<span class=\"hljs-keyword\">NULL<\/span>, size, <span class=\"hljs-keyword\">false<\/span>);\n    <span class=\"hljs-keyword\">return<\/span> first + <span class=\"hljs-number\">1<\/span>;\n  }\n  Header *header = first;\n  <span class=\"hljs-keyword\">while<\/span> (header != <span class=\"hljs-keyword\">NULL<\/span>) {\n    <span class=\"hljs-keyword\">if<\/span> (header-&gt;available &amp;&amp; (header-&gt;size &gt;= size)) {\n      header-&gt;available = <span class=\"hljs-keyword\">false<\/span>;\n      <span class=\"hljs-keyword\">return<\/span> header + <span class=\"hljs-number\">1<\/span>;\n    }\n    header = header-&gt;next;\n  }\n  last = header_new(last, size, <span class=\"hljs-keyword\">false<\/span>);\n  last-&gt;previous-&gt;next = last;\n  <span class=\"hljs-keyword\">return<\/span> last + <span class=\"hljs-number\">1<\/span>;\n}\n\nvoid abfree(void *ptr) {\n  <span class=\"hljs-keyword\">if<\/span> (ptr == <span class=\"hljs-keyword\">NULL<\/span>) {\n   <span class=\"hljs-keyword\">return<\/span>;\n  }\n  Header *header = (Header*) ptr - <span class=\"hljs-number\">1<\/span>;\n  <span class=\"hljs-keyword\">if<\/span> (header == last) {\n    <span class=\"hljs-keyword\">while<\/span> ((header-&gt;previous != <span class=\"hljs-keyword\">NULL<\/span>) &amp;&amp; header-&gt;previous-&gt;available) {\n      header = header-&gt;previous;\n    }\n    last = header-&gt;previous;\n    <span class=\"hljs-keyword\">if<\/span> (last != <span class=\"hljs-keyword\">NULL<\/span>) {\n      last-&gt;next = <span class=\"hljs-keyword\">NULL<\/span>;\n    } <span class=\"hljs-keyword\">else<\/span> {\n      first = <span class=\"hljs-keyword\">NULL<\/span>;\n    }\n    brk(header);\n  } <span class=\"hljs-keyword\">else<\/span> {\n   header-&gt;available = <span class=\"hljs-keyword\">true<\/span>;\n  }\n }<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Esta mudan\u00e7a nos permite economizar consideravelmente mais mem\u00f3ria. Existem, contudo, problemas a resolver ainda. Por exemplo, considere o seguinte cen\u00e1rio: solicitamos a aloca\u00e7\u00e3o de um bloco de mem\u00f3ria de 8 bytes, e <code>abmalloc()<\/code> reaproveita um boco de, digamos, 1024 bytes. H\u00e1 claramente um desperd\u00edcio.<\/p>\n\n\n\n<p>Veremos como resolver isso no <a href=\"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-dividindo-blocos-grandes\/\">pr\u00f3ximo <em>post<\/em><\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>No post anterior desta s\u00e9rie sobre a implementa\u00e7\u00e3o das fun\u00e7\u00f5es malloc() e free(), mostramos como \u00e9 poss\u00edvel reutilizar blocos de mem\u00f3ria e reduzir o heap ao liberar os blocos mais novos. No entanto, a fun\u00e7\u00e3o atual reutiliza o bloco de mem\u00f3ria livre mais recente, levando a um consumo de mem\u00f3ria maior. Vamos analisar como isso [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":663,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-617","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/suspensao.blog.br\/descrenca\/wp-content\/uploads\/2024\/09\/The-lower-part-of-the-Sanaa-manuscript-which-was-scrapped-and-written-over-an-original-text.-An-old-and-reused-parchment.jpg?fit=1077%2C480&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p23QLV-9X","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/617","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/comments?post=617"}],"version-history":[{"count":14,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/617\/revisions"}],"predecessor-version":[{"id":701,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/617\/revisions\/701"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/media\/663"}],"wp:attachment":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/media?parent=617"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/categories?post=617"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/tags?post=617"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}