{"id":615,"date":"2024-04-15T11:25:00","date_gmt":"2024-04-15T14:25:00","guid":{"rendered":"https:\/\/suspensao.blog.br\/descrenca\/?p=615"},"modified":"2024-05-26T23:30:36","modified_gmt":"2024-05-27T02:30:36","slug":"implementando-malloc-e-free-reduzindo-ainda-mais-o-heap","status":"publish","type":"post","link":"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-reduzindo-ainda-mais-o-heap\/","title":{"rendered":"Implementando malloc() e free() \u2014 reduzindo ainda mais o heap"},"content":{"rendered":"\n<p>Este post faz parte de uma s\u00e9rie sobre como implementar as fun\u00e7\u00f5es <code>malloc()<\/code> e <code>free()<\/code>. No <a href=\"https:\/\/suspensao.blog.br\/descrenca\/implementando-malloc-e-free-reutilizando-blocos-de-memoria\/\">artigo anterior<\/a>, aprendemos como reutilizar blocos de mem\u00f3ria. Foi um grande avan\u00e7o, mas h\u00e1 muito mais a melhorar.<\/p>\n\n\n\n<p>Um exemplo \u00e9 a redu\u00e7\u00e3o do tamanho do <em>heap<\/em>. Quando liberamos o \u00faltimo bloco de mem\u00f3ria, movemos o topo do <em>heap<\/em> para fim do bloco anterior. Contudo, este bloco anterior pode tamb\u00e9m estar livre, assim como outros. Considere o caso abaixo:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">void *ptr1 = abmalloc(8);<br>void *ptr2 = abmalloc(8);<br>abfree(ptr1);<br>abfree(ptr2);<\/pre>\n\n\n\n<p>Neste caso, ao liberarmos o bloco apontado por <code>ptr2<\/code>, fazemos com que <code>ptr1<\/code> seja o \u00faltimo bloco. Contudo, <code>ptr1<\/code> tamb\u00e9m est\u00e1 livre, ent\u00e3o poder\u00edamos reduzir ainda mais o tamanho do heap.<\/p>\n\n\n\n<p>Para isso, vamos iterar sobre os ponteiros do final da lista at\u00e9 n\u00e3o haver mais blocos livres. Se o cabe\u00e7alho do ponteiro recebido apontar para o \u00faltimo bloco e o bloco anterior estiver livre, movemos o ponteiro de cabe\u00e7alho para ele. Repetimos esse processo at\u00e9 chegar a um bloco dispon\u00edvel cujo anterior esteja em uso (ou seja <code>NULL<\/code>, caso seja o primeiro bloco). Em seguida, executamos o procedimento de redu\u00e7\u00e3o do heap:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">  if (header == last) {<br>    while ((header-&gt;previous != NULL) &amp;&amp; header-&gt;previous-&gt;available) {<br>      header = header-&gt;previous;<br>    }<br>    last = header-&gt;previous;<br>    brk(header);<br>  } else {<\/pre>\n\n\n\n<p>Agora, por\u00e9m, precisamos corrigir um bug em <code>abfree(<\/code>). De acordo com a especifica\u00e7\u00e3o, <a href=\"http:\/\/pubs.opengroup.org\/onlinepubs\/009695399\/functions\/free.html\">a fun\u00e7\u00e3o <code>free()<\/code> deve aceitar o ponteiro nulo e n\u00e3o fazer nada<\/a>. Se <code>abfree()<\/code> receber <code>NULL<\/code>, teremos uma falha de segmenta\u00e7\u00e3o! Felizmente, isto \u00e9 f\u00e1cil de resolver adicionando uma verifica\u00e7\u00e3o no in\u00edcio da fun\u00e7\u00e3o:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">void abfree(void *ptr) {\n   if (ptr == NULL) {\n     return;\n   }\n   Header *header = (Header*) ptr - 1<\/pre>\n\n\n\n<p>E assim fica nossa fun\u00e7\u00e3o <code>abfree()<\/code> at\u00e9 o momento:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">void abfree(void *ptr) {\n   if (ptr == NULL) {\n     return;\n   }\n   Header *header = (Header*) ptr - 1;\n   if (header == last) {\n     while ((header-&gt;previous != NULL) &amp;&amp; header-&gt;previous-&gt;available) {\n       header = header-&gt;previous;\n     }\n     last = header-&gt;previous;\n     brk(header);\n   } else {\n     header-&gt;available = true;\n   }\n }<\/pre>\n\n\n\n<p>Reduzir o tamanho do heap \u00e9 uma otimiza\u00e7\u00e3o simples, mas ainda h\u00e1 desafios a serem enfrentados. Por exemplo, a maneira com que escolhemos qual bloco reutilizar pode levar a <em>heaps<\/em> maiores que o necess\u00e1rio. Veremos por que isto acontece, e como resolver isto, no <a href=\"https:\/\/suspensao.blog.br\/descrenca\/?p=617\">pr\u00f3ximo post<\/a>. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Este post faz parte de uma s\u00e9rie sobre como implementar as fun\u00e7\u00f5es malloc() e free(). No artigo anterior, aprendemos como reutilizar blocos de mem\u00f3ria. Foi um grande avan\u00e7o, mas h\u00e1 muito mais a melhorar. Um exemplo \u00e9 a redu\u00e7\u00e3o do tamanho do heap. Quando liberamos o \u00faltimo bloco de mem\u00f3ria, movemos o topo do heap [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"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":"Prosseguindo com nossa s\u00e9rie sobre malloc() and free(), vamos ver como podemos reduzir ainda mais o tamanho do heap.","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":[29,179,10,12],"tags":[79,180,171,96,170],"class_list":["post-615","post","type-post","status-publish","format-standard","hentry","category-c","category-libc","category-linux","category-programacao","tag-c","tag-desenvolvimento-de-software","tag-gerenciamento-de-memoria","tag-linguagens-de-programacao","tag-malloc"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p23QLV-9V","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/615","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=615"}],"version-history":[{"count":9,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/615\/revisions"}],"predecessor-version":[{"id":661,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/615\/revisions\/661"}],"wp:attachment":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/media?parent=615"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/categories?post=615"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/tags?post=615"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}