Implementando malloc() e free() — memória antiga tem preferência

You are viewing an old revision of this post, from September 16, 2024 @ 17:43:14. See below for differences between this version and the current revision.

No post anterior desta série sobre a implementação das funções malloc() e free(), mostramos como é possível reutilizar blocos de memória e reduzir o heap ao liberar os blocos mais novos. No entanto, a função atual tem um comportamento que sutilmente leva a um consumo de memória maior: ela escolhe blocos de memória mais recentes para reutilizar. Por que isso é um problema? Vamos analisar como isso ocorre.

Redução do heap com reaproveitamento de blocos recentes

Considere o cenário a seguir. Primeiro, alocamos quatro blocos de memória:

void *ptr1 = abmalloc(8);
void *ptr2 = abmalloc(8);
void *ptr3 = abmalloc(8);
void *ptr4 = abmalloc(8);

A estrutura em memória pode ser visualizada assim:

Lista ligada com quatro nós. Os nós mais novos apontam para os mais antigos. Todos os nós estão em uso, por isso todos estão com o rótulo Ocupado.

Agora, liberamos o primeiro e o terceiro bloco…

abfree(ptr1);
abfree(ptr3);

…resultando na seguinte estrutura:

Lista ligada com quatro nós. Os nós mais novos apontam para os mais antigos. O segundo e quarto nós da lista (ou seja, o segundo mais novo e o mais antigo de todos) foram liberados com free(), então estão rotulados com a palavra Livre.

Em seguida, alocamos outro bloco do mesmo tamanho:

void *ptr5 = abmalloc(8); 

Como função abmalloc() começa a busca pelo bloco livre mais recente, ela reutiliza o bloco que está no topo. Se agora liberarmos o último bloco:

Lista ligada com quatro nós. Os nós mais novos apontam para os mais antigos. Agora apenas o últmo nó está liberado e rotulado com a palavra Livre

Se, agora, liberamos o último bloco…

abfree(ptr4);

…poderemos reduzir o tamanho do heap em apenas um bloco de 8 bytes, já que o penúltimo bloco não está mais livre:

Lista ligada com três nós. Os nós mais novos apontam para os mais antigos. O último nó está liberado e rotulado com a palavra Livre

Reaproveitamento de blocos antigos

Agora, imagine o mesmo cenário, mas com uma modificação: nossa função busca blocos livres começando pelo mais antigo.

A estrutura inicial será a mesma…

Lista ligada com quatro nós. Os nós mais antigos apontam para os mais novos. Todos os nós estão em uso e rotulados com a palavra Ocupado.

…e novamente liberamos o primeiro e o terceiro bloco de memória:

Lista ligada com quatro nós. Os nós mais antigos apontam para os mais novos. O primeiro e terceiro nós (isto é, o mais antigo e o terceiro mais antigo/segundo mais novo) foram desalocados e estão rotulados com a palavra Livre

Dessa vez, o primeiro bloco será reutilizado:

Lista ligada com quatro nós. Os nós mais antigos apontam para os mais novos. O terceiro nós (isto é, o mais antigo e o terceiro mais antigo/segundo mais novo) foi desalocado. Por isso, está rotulado com a palavra Livre

Agora, ao liberarmos o último bloco, teremos dois blocos livres no topo, permitindo reduzir o heap em dois blocos de 8 bytes:

Lista ligada com dois nós.  Todos estão ocupados porque os nós livres estavam no topo do heap e, portanto, foram destruídos.

Esse exemplo ilustra como, ao dar preferência a blocos mais novos, acabamos acumulando blocos livres antigos, desperdiçando memória e levando a um crescimento desnecessário do heap. A solução é modificar a estratégia de busca, priorizando a reutilização de blocos mais antigos.

Implementando preferência por blocos antigos

Para resolver esse problema, vamos implementar uma nova abordagem no código. Primeiramente, vamos adicionar ao cabeçalho dos blocos um ponteiro para o próximo bloco, permitindo percorrermos a memória de maneira eficiente. Também adicionaremos um ponteiro para o primeiro bloco, o que facilitará a busca:

typedef struct Header {
struct Header *previous, *next;
size_t size;
bool available;
} Header;

Header *first = NULL;
Header *last = NULL;

Agora, faremos uma pequena refatoração. Como criamos blocos de memória com headers em duas situações diferentes, extrairemos essa lógica para uma função auxiliar que aloca e inicializa o cabeçalho (inclusive setando o campo next com NULL):

Header *header_new(Header *previous, size_t size, bool available) {
Header *header = sbrk(sizeof(Header) + size);
header->previous = previous;
header->next = NULL;
header->size = size;
header->available = false;
return header;
}

Com essa nova função, podemos simplificar a lógica dentro de abmalloc():

void *abmalloc(size_t size) {
if (size == 0) {
return NULL;
}
Header *header = last;
while (header != NULL) {
if (header->available && (header->size >= size)) {
header->available = false;
return header + 1;
}
header = header->previous;
}
last = header_new(last, size, false);
return last + 1;
}

Agora temos acesso ao primeiro e último blocos e, dado um bloco, podemos descobrir o anterior e o posterior. Sabemos, também, que quando o ponteiro para o primeiro bloco for nulo, nenhum bloco terá sido alocado ainda. Então, neste caso, alocaremos o bloco imediatamente, e inicializaremos tanto first quanto last:

void *abmalloc(size_t size) {
if (size == 0) {
return NULL;
}
if (first == NULL) {
first = last = header_new(NULL, size, false);
return first + 1;
}

Se first não é mais NULL, já existem blocos alocados, então começaremos a busca por um bloco reutilizável. Continuaremos utilizando a variável header como iterador, mas, em vez de começar pelo bloco mais recente, a pesquisa será iniciada a partir do mais antigo:

  Header *header = first;

A cada iteração, avançaremos para o próximo bloco na sequência, em vez de retroceder para o bloco anterior:

  while (header != NULL) {
if (header->available && (header->size >= size)) {
header->available = false;
return header + 1;
}
header = header->next;
}

A lógica permanece a mesma: se encontramos um bloco disponível e de tamanho suficiente, ele é retornado. Caso contrário, se nenhum bloco reutilizável for encontrado após percorrermos a lista, um novo bloco será alocado:

  last = header_new(last, size, false);

Agora, precisamos ajustar o bloco que era o último (e que, após a alocação, passa a ser o penúltimo). Ele apontava para NULL, mas agora deve apontar para o novo bloco. Para isso, acessamos o ponteiro previous do novo último bloco e atualizamos o campo next do bloco anterior:

  last->previous->next = last;
return last + 1;
}

Ajustes na Função abfree()

A função abfree() mantém basicamente a mesma estrutura, mas agora devemos tratar alguns casos de borda. Quando liberamos blocos no topo do heap, um novo bloco passa a ser o último, conforme já fazemos neste trecho:

    last = header->previous;
brk(header)

Aqui, o ponteiro header referencia o último bloco não nulo e disponível na pilha. Temos dois cenários possíveis: no primeiro, o bloco atual possui um bloco anterior, que se tornará o novo último bloco. Nesse caso, devemos ajustar o ponteiro next desse bloco para NULL. No segundo cenário, o bloco atual não possui um bloco anterior (ou seja, ele é o primeiro e mais antigo bloco). Quando ele é liberado, a pilha fica vazia. Nesse caso, em vez de tentar atualizar um campo de um bloco inexistente, basta definirmos first como NULL, indicando que não há mais blocos alocados:

  last = header->previous;
if (last != NULL) {
last->next = NULL;
} else {
first = NULL;
}
brk(header);

Conclusão

Nossas funções abmalloc() e abfree() agora estão assim:

typedef struct Header {
  struct Header *previous, *next;
  size_t size;
  bool available;
} Header;

Header *first = NULL;
Header *last = NULL;

Header *header_new(Header *previous, size_t size, bool available) {
  Header *header = sbrk(sizeof(Header) + size);
  header->previous = previous;
  header->next = NULL;
  header->size = size;
  header->available = false;
  return header;
}

void *abmalloc(size_t size) {
  if (size == 0) {
    return NULL;
  }
  if (first == NULL) {
    first = last = header_new(NULL, size, false);
    return first + 1;
  }
  Header *header = first;
  while (header != NULL) {
    if (header->available && (header->size >= size)) {
      header->available = false;
      return header + 1;
    }
    header = header->next;
  }
  last = header_new(last, size, false);
  last->previous->next = last;
  return last + 1;
}

void abfree(void *ptr) {
  if (ptr == NULL) {
   return;
  }
  Header *header = (Header*) ptr - 1;
  if (header == last) {
    while ((header->previous != NULL) && header->previous->available) {
      header = header->previous;
    }
    last = header->previous;
    if (last != NULL) {
      last->next = NULL;
    } else {
      first = NULL;
    }
    brk(header);
  } else {
   header->available = true;
  }
 }Code language: PHP (php)

Esta mudança nos permite economizar consideravelmente mais memória. Existem, contudo, problemas a resolver ainda. Por exemplo, considere o seguinte cenário: solicitamos a alocação de um bloco de memória de 8 bytes, e abmalloc() reaproveita um boco de, digamos, 1024 bytes. Há claramente um desperdício.

Veremos como resolver isso no próximo post.

Post Revisions:

Changes:

September 16, 2024 @ 17:43:14Current Revision
Content
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Deleted: <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érie sobre a implementação das funções <code>malloc()</code> e <code>free()</code>, mostramos como é possível reutilizar blocos de memória e reduzir o <em>heap</em> ao liberar os blocos mais novos. No entanto, a função atual tem um comportamento que sutilmente leva a um consumo de memória maior: ela escolhe blocos de memória mais recentes para reutilizar. Por que isso é um problema? Vamos analisar como isso ocorre.</p> Added: <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érie sobre a implementação de <code>malloc()</code> e <code>free()</code>, mostramos como é possível reutilizar blocos de memória e reduzir o <em>heap</em> ao liberar os blocos mais novos. No entanto, a função atual tem um comportamento que sutilmente leva a um consumo de memória maior: ela escolhe blocos de memória mais recentes para reutilizar. Por que isso é um problema? Vamos analisar como isso ocorre.</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:heading {"level":3} -->Unchanged: <!-- wp:heading {"level":3} -->
Unchanged: <h3 class="wp-block- heading">Redução do <em>heap</em> com reaproveitamento de blocos recentes</h3>Unchanged: <h3 class="wp-block- heading">Redução do <em>heap</em> com reaproveitamento de blocos recentes</h3>
Unchanged: <!-- /wp:heading -->Unchanged: <!-- /wp:heading -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Considere o cenário a seguir. Primeiro, alocamos quatro blocos de memória:</p>Unchanged: <p>Considere o cenário a seguir. Primeiro, alocamos quatro blocos de memória:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <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> Added: <pre class="wp-block- code"><code>void *ptr1 = abmalloc(8);<br>void *ptr2 = abmalloc(8);<br>void *ptr3 = abmalloc(8);<br>void *ptr4 = abmalloc(8); </code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>A estrutura em memória pode ser visualizada assim:</p>Unchanged: <p>A estrutura em memória pode ser visualizada assim:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:image {"id":646,"width" :"auto","height":"50px"," sizeSlug":"large" ,"linkDestination" :"media","align":"center"} -->Unchanged: <!-- wp:image {"id":646,"width" :"auto","height":"50px"," sizeSlug":"large" ,"linkDestination" :"media","align":"center"} -->
Unchanged: <figure class="wp-block-image aligncenter size-large is-resized"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-inicial- atual.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-inicial-atual.svg" alt="Lista ligada com quatro nós. Os nós mais novos apontam para os mais antigos. Todos os nós estão em uso, por isso todos estão com o rótulo Ocupado." class="wp-image-646" style="width: auto;height:50px" /></a></figure>Unchanged: <figure class="wp-block-image aligncenter size-large is-resized"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-inicial- atual.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-inicial-atual.svg" alt="Lista ligada com quatro nós. Os nós mais novos apontam para os mais antigos. Todos os nós estão em uso, por isso todos estão com o rótulo Ocupado." class="wp-image-646" style="width: auto;height:50px" /></a></figure>
Unchanged: <!-- /wp:image -->Unchanged: <!-- /wp:image -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Agora, liberamos o primeiro e o terceiro bloco...</p>Unchanged: <p>Agora, liberamos o primeiro e o terceiro bloco...</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <pre class="wp-block- preformatted" >abfree(ptr1) ;<br>abfree(ptr3); </pre> Added: <pre class="wp-block- code"><code>abfree(ptr1); <br>abfree(ptr3); </code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>...resultando na seguinte estrutura:</p>Unchanged: <p>...resultando na seguinte estrutura:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:image {"id":648,"sizeSlug" :"medium","linkDestination" :"media","align":"center"} -->Unchanged: <!-- wp:image {"id":648,"sizeSlug" :"medium","linkDestination" :"media","align":"center"} -->
Unchanged: <figure class="wp-block-image aligncenter size-medium"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-liberada- atual-1.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-liberada- atual-1.svg" alt="Lista ligada com quatro nós. Os nós mais novos apontam para os mais antigos. O segundo e quarto nós da lista (ou seja, o segundo mais novo e o mais antigo de todos) foram liberados com free(), então estão rotulados com a palavra Livre." class="wp-image- 648"/></a></figure>Unchanged: <figure class="wp-block-image aligncenter size-medium"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-liberada- atual-1.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-liberada- atual-1.svg" alt="Lista ligada com quatro nós. Os nós mais novos apontam para os mais antigos. O segundo e quarto nós da lista (ou seja, o segundo mais novo e o mais antigo de todos) foram liberados com free(), então estão rotulados com a palavra Livre." class="wp-image- 648"/></a></figure>
Unchanged: <!-- /wp:image -->Unchanged: <!-- /wp:image -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Em seguida, alocamos outro bloco do mesmo tamanho:</p>Unchanged: <p>Em seguida, alocamos outro bloco do mesmo tamanho:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <pre class="wp-block- preformatted">void *ptr5 = abmalloc(8); </pre> Added: <pre class="wp-block- code"><code>void *ptr5 = abmalloc(8); </code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Como função <code>abmalloc()</code> começa a busca pelo bloco livre mais recente, ela reutiliza o bloco que está no topo. Se agora liberarmos o último bloco:</p>Unchanged: <p>Como função <code>abmalloc()</code> começa a busca pelo bloco livre mais recente, ela reutiliza o bloco que está no topo. Se agora liberarmos o último bloco:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:image {"id":649,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->Unchanged: <!-- wp:image {"id":649,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->
Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-realocada- atual.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-realocada-atual.svg" alt="Lista ligada com quatro nós. Os nós mais novos apontam para os mais antigos. Agora apenas o últmo nó está liberado e rotulado com a palavra Livre" class="wp-image- 649"/></a></figure>Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-realocada- atual.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-realocada-atual.svg" alt="Lista ligada com quatro nós. Os nós mais novos apontam para os mais antigos. Agora apenas o últmo nó está liberado e rotulado com a palavra Livre" class="wp-image- 649"/></a></figure>
Unchanged: <!-- /wp:image -->Unchanged: <!-- /wp:image -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Se, agora, liberamos o último bloco...</p>Unchanged: <p>Se, agora, liberamos o último bloco...</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <pre class="wp-block- preformatted" >abfree(ptr4);</pre> Added: <pre class="wp-block- code"><code>abfree(ptr4); </code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>...poderemos reduzir o tamanho do <em>heap</em> em apenas um bloco de 8 bytes, já que o penúltimo bloco não está mais livre:</p>Unchanged: <p>...poderemos reduzir o tamanho do <em>heap</em> em apenas um bloco de 8 bytes, já que o penúltimo bloco não está mais livre:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:image {"id":650,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->Unchanged: <!-- wp:image {"id":650,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->
Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-heap-reduzido- atual.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-heap-reduzido-atual.svg" alt="Lista ligada com três nós. Os nós mais novos apontam para os mais antigos. O último nó está liberado e rotulado com a palavra Livre" class="wp-image- 650"/></a></figure>Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-heap-reduzido- atual.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-heap-reduzido-atual.svg" alt="Lista ligada com três nós. Os nós mais novos apontam para os mais antigos. O último nó está liberado e rotulado com a palavra Livre" class="wp-image- 650"/></a></figure>
Unchanged: <!-- /wp:image -->Unchanged: <!-- /wp:image -->
Unchanged: <!-- wp:heading {"level":3} -->Unchanged: <!-- wp:heading {"level":3} -->
Unchanged: <h3 class="wp-block- heading">Reaproveitamento de blocos antigos</h3>Unchanged: <h3 class="wp-block- heading">Reaproveitamento de blocos antigos</h3>
Unchanged: <!-- /wp:heading -->Unchanged: <!-- /wp:heading -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Agora, imagine o mesmo cenário, mas com uma modificação: nossa função busca blocos livres começando pelo mais antigo.</p>Unchanged: <p>Agora, imagine o mesmo cenário, mas com uma modificação: nossa função busca blocos livres começando pelo mais antigo.</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>A estrutura inicial será a mesma...</p>Unchanged: <p>A estrutura inicial será a mesma...</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:image {"id":651,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->Unchanged: <!-- wp:image {"id":651,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->
Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-inicial- desejada.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-inicial- desejada.svg" alt="Lista ligada com quatro nós. Os nós mais antigos apontam para os mais novos. Todos os nós estão em uso e rotulados com a palavra Ocupado." class="wp-image- 651"/></a></figure>Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-inicial- desejada.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-inicial- desejada.svg" alt="Lista ligada com quatro nós. Os nós mais antigos apontam para os mais novos. Todos os nós estão em uso e rotulados com a palavra Ocupado." class="wp-image- 651"/></a></figure>
Unchanged: <!-- /wp:image -->Unchanged: <!-- /wp:image -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>...e novamente liberamos o primeiro e o terceiro bloco de memória:</p>Unchanged: <p>...e novamente liberamos o primeiro e o terceiro bloco de memória:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:image {"id":652,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->Unchanged: <!-- wp:image {"id":652,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->
Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-liberada- desejada.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-liberada- desejada.svg" alt="Lista ligada com quatro nós. Os nós mais antigos apontam para os mais novos. O primeiro e terceiro nós (isto é, o mais antigo e o terceiro mais antigo/segundo mais novo) foram desalocados e estão rotulados com a palavra Livre" class="wp-image- 652"/></a></figure>Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-liberada- desejada.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-liberada- desejada.svg" alt="Lista ligada com quatro nós. Os nós mais antigos apontam para os mais novos. O primeiro e terceiro nós (isto é, o mais antigo e o terceiro mais antigo/segundo mais novo) foram desalocados e estão rotulados com a palavra Livre" class="wp-image- 652"/></a></figure>
Unchanged: <!-- /wp:image -->Unchanged: <!-- /wp:image -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Dessa vez, o primeiro bloco será reutilizado:</p>Unchanged: <p>Dessa vez, o primeiro bloco será reutilizado:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:image {"id":653,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->Unchanged: <!-- wp:image {"id":653,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->
Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-realocada- desejada.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-realocada- desejada.svg" alt="Lista ligada com quatro nós. Os nós mais antigos apontam para os mais novos. O terceiro nós (isto é, o mais antigo e o terceiro mais antigo/segundo mais novo) foi desalocado. Por isso, está rotulado com a palavra Livre" class="wp-image- 653"/></a></figure>Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-realocada- desejada.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-realocada- desejada.svg" alt="Lista ligada com quatro nós. Os nós mais antigos apontam para os mais novos. O terceiro nós (isto é, o mais antigo e o terceiro mais antigo/segundo mais novo) foi desalocado. Por isso, está rotulado com a palavra Livre" class="wp-image- 653"/></a></figure>
Unchanged: <!-- /wp:image -->Unchanged: <!-- /wp:image -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Agora, ao liberarmos o último bloco, teremos dois blocos livres no topo, permitindo reduzir o <em>heap</em> em dois blocos de 8 bytes:</p>Unchanged: <p>Agora, ao liberarmos o último bloco, teremos dois blocos livres no topo, permitindo reduzir o <em>heap</em> em dois blocos de 8 bytes:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:image {"id":654,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->Unchanged: <!-- wp:image {"id":654,"sizeSlug" :"large","linkDestination" :"media","align":"center"} -->
Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-heap-reduzido- desejada.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-heap-reduzido- desejada.svg" alt="Lista ligada com dois nós. Todos estão ocupados porque os nós livres estavam no topo do heap e, portanto, foram destruídos." class="wp-image- 654"/></a></figure>Unchanged: <figure class="wp-block-image aligncenter size-large"><a href="https:/ /suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-heap-reduzido- desejada.svg"><img src="https:// suspensao.blog.br/descrenca/ wp-content/uploads/2024/05/ lista-heap-reduzido- desejada.svg" alt="Lista ligada com dois nós. Todos estão ocupados porque os nós livres estavam no topo do heap e, portanto, foram destruídos." class="wp-image- 654"/></a></figure>
Unchanged: <!-- /wp:image -->Unchanged: <!-- /wp:image -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Esse exemplo ilustra como, ao dar preferência a blocos mais novos, acabamos acumulando blocos livres antigos, desperdiçando memória e levando a um crescimento desnecessário do <em>heap</em>. A solução é modificar a estratégia de busca, priorizando a reutilização de blocos mais antigos.</p>Unchanged: <p>Esse exemplo ilustra como, ao dar preferência a blocos mais novos, acabamos acumulando blocos livres antigos, desperdiçando memória e levando a um crescimento desnecessário do <em>heap</em>. A solução é modificar a estratégia de busca, priorizando a reutilização de blocos mais antigos.</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:heading {"level":3} -->Unchanged: <!-- wp:heading {"level":3} -->
Unchanged: <h3 class="wp-block- heading">Implementando preferência por blocos antigos</h3>Unchanged: <h3 class="wp-block- heading">Implementando preferência por blocos antigos</h3>
Unchanged: <!-- /wp:heading -->Unchanged: <!-- /wp:heading -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Deleted: <p>Para resolver esse problema, vamos implementar uma nova abordagem no código. Primeiramente, vamos adicionar ao cabeçalho dos blocos um ponteiro para o próximo bloco, permitindo percorrermos a memória de maneira eficiente. Também adicionaremos um ponteiro para o primeiro bloco, o que facilitará a busca:</p> Added: <p>Para resolver esse problema, vamos implementar uma nova abordagem no código. Primeiramente, vamos adicionar ao cabeçalho dos blocos um ponteiro para o próximo bloco, permitindo percorrermos a memória de maneira eficiente. Também criaremos um ponteiro global para o primeiro bloco, o que facilitará a busca:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <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> Added: <pre class="wp-block- code"><code>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;</code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Agora, faremos uma pequena refatoração. Como criamos blocos de memória com headers em duas situações diferentes, extrairemos essa lógica para uma função auxiliar que aloca e inicializa o cabeçalho (inclusive setando o campo <code>next</code> com <code>NULL</code>):</p>Unchanged: <p>Agora, faremos uma pequena refatoração. Como criamos blocos de memória com headers em duas situações diferentes, extrairemos essa lógica para uma função auxiliar que aloca e inicializa o cabeçalho (inclusive setando o campo <code>next</code> com <code>NULL</code>):</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <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> Added: <pre class="wp-block- code"><code>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>}< /code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Com essa nova função, podemos simplificar a lógica dentro de <code>abmalloc( )</code>:</p>Unchanged: <p>Com essa nova função, podemos simplificar a lógica dentro de <code>abmalloc( )</code>:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <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> Added: <pre class="wp-block- code"><code>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>}</code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Agora temos acesso ao primeiro e último blocos e, dado um bloco, podemos descobrir o anterior e o posterior. Sabemos, também, que quando o ponteiro para o primeiro bloco for nulo, nenhum bloco terá sido alocado ainda. Então, neste caso, alocaremos o bloco imediatamente, e inicializaremos tanto first quanto last:</p>Unchanged: <p>Agora temos acesso ao primeiro e último blocos e, dado um bloco, podemos descobrir o anterior e o posterior. Sabemos, também, que quando o ponteiro para o primeiro bloco for nulo, nenhum bloco terá sido alocado ainda. Então, neste caso, alocaremos o bloco imediatamente, e inicializaremos tanto first quanto last:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <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> Added: <pre class="wp-block- code"><code>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> }</code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Se <code>first</code> não é mais <code>NULL</code>, já existem blocos alocados, então começaremos a busca por um bloco reutilizável. Continuaremos utilizando a variável <code>header</code> como iterador, mas, em vez de começar pelo bloco mais recente, a pesquisa será iniciada a partir do mais antigo:</p>Unchanged: <p>Se <code>first</code> não é mais <code>NULL</code>, já existem blocos alocados, então começaremos a busca por um bloco reutilizável. Continuaremos utilizando a variável <code>header</code> como iterador, mas, em vez de começar pelo bloco mais recente, a pesquisa será iniciada a partir do mais antigo:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <pre class="wp-block- preformatted"> Header *header = first;</pre> Added: <pre class="wp-block- code"><code> Header *header = first;</code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>A cada iteração, avançaremos para o próximo bloco na sequência, em vez de retroceder para o bloco anterior:</p>Unchanged: <p>A cada iteração, avançaremos para o próximo bloco na sequência, em vez de retroceder para o bloco anterior:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <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> Added: <pre class="wp-block- code"><code> 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> }</code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>A lógica permanece a mesma: se encontramos um bloco disponível e de tamanho suficiente, ele é retornado. Caso contrário, se nenhum bloco reutilizável for encontrado após percorrermos a lista, um novo bloco será alocado:</p>Unchanged: <p>A lógica permanece a mesma: se encontramos um bloco disponível e de tamanho suficiente, ele é retornado. Caso contrário, se nenhum bloco reutilizável for encontrado após percorrermos a lista, um novo bloco será alocado:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <pre class="wp-block- preformatted"> last = header_new(last, size, false);<br></pre> Added: <pre class="wp-block- code"><code> last = header_new(last, size, false);<br></code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Agora, precisamos ajustar o bloco que era o último (e que, após a alocação, passa a ser o penúltimo). Ele apontava para <code>NULL</code>, mas agora deve apontar para o novo bloco. Para isso, acessamos o ponteiro <code>previous</code> do novo último bloco e atualizamos o campo <code>next</code> do bloco anterior:</p>Unchanged: <p>Agora, precisamos ajustar o bloco que era o último (e que, após a alocação, passa a ser o penúltimo). Ele apontava para <code>NULL</code>, mas agora deve apontar para o novo bloco. Para isso, acessamos o ponteiro <code>previous</code> do novo último bloco e atualizamos o campo <code>next</code> do bloco anterior:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <pre class="wp-block- preformatted"> last-&gt;previous-&gt;next = last;<br> return last + 1;<br>}</pre> Added: <pre class="wp-block- code"><code> last-&gt;previous-&gt;next = last;<br> return last + 1;<br>}</code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:heading {"level":3} -->Unchanged: <!-- wp:heading {"level":3} -->
Unchanged: <h3 class="wp-block- heading">Ajustes na Função <code>abfree( )</code></h3>Unchanged: <h3 class="wp-block- heading">Ajustes na Função <code>abfree( )</code></h3>
Unchanged: <!-- /wp:heading -->Unchanged: <!-- /wp:heading -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>A função <code>abfree()</code> mantém 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 último, conforme já fazemos neste trecho:</p>Unchanged: <p>A função <code>abfree()</code> mantém 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 último, conforme já fazemos neste trecho:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <pre class="wp-block- preformatted"> last = header-&gt;previous;<br> brk(header)</pre> Added: <pre class="wp-block- code"><code> last = header-&gt;previous;<br> brk(header)</code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Aqui, o ponteiro <code>header</code> referencia o último bloco não nulo e disponível na pilha. Temos dois cenários possíveis: no primeiro, o bloco atual possui um bloco anterior, que se tornará o novo último bloco. Nesse caso, devemos ajustar o ponteiro <code>next</code> desse bloco para <code>NULL</code>. No segundo cenário, o bloco atual não possui um bloco anterior (ou seja, ele é o primeiro e mais antigo bloco). Quando ele é 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ão há mais blocos alocados:</p>Unchanged: <p>Aqui, o ponteiro <code>header</code> referencia o último bloco não nulo e disponível na pilha. Temos dois cenários possíveis: no primeiro, o bloco atual possui um bloco anterior, que se tornará o novo último bloco. Nesse caso, devemos ajustar o ponteiro <code>next</code> desse bloco para <code>NULL</code>. No segundo cenário, o bloco atual não possui um bloco anterior (ou seja, ele é o primeiro e mais antigo bloco). Quando ele é 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ão há mais blocos alocados:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Deleted: <!-- wp:preformatted --> Added: <!-- wp:code -->
Deleted: <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> Added: <pre class="wp-block- code"><code> last = header-&gt;previous;<br> if (last != NULL) {<br> last-&gt;next = NULL;<br> } else {<br> first = NULL;<br> }<br> brk(header);< /code></pre>
Deleted: <!-- /wp:preformatted --> Added: <!-- /wp:code -->
Unchanged: <!-- wp:heading {"level":3} -->Unchanged: <!-- wp:heading {"level":3} -->
Unchanged: <h3 class="wp-block- heading">Conclusão</h3>Unchanged: <h3 class="wp-block- heading">Conclusão</h3>
Unchanged: <!-- /wp:heading -->Unchanged: <!-- /wp:heading -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Nossas funções <code>abmalloc()</code> e <code>abfree()</code> agora estão assim:</p>Unchanged: <p>Nossas funções <code>abmalloc()</code> e <code>abfree()</code> agora estão assim:</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:code -->Unchanged: <!-- wp:code -->
Unchanged: <pre class="wp-block- code"><code>typedef struct Header {Unchanged: <pre class="wp-block- code"><code>typedef struct Header {
Unchanged: struct Header *previous, *next;Unchanged: struct Header *previous, *next;
Unchanged: size_t size;Unchanged: size_t size;
Unchanged: bool available;Unchanged: bool available;
Unchanged: } Header;Unchanged: } Header;
Unchanged: Header *first = NULL;Unchanged: Header *first = NULL;
Unchanged: Header *last = NULL;Unchanged: Header *last = NULL;
Unchanged: Header *header_new(Header *previous, size_t size, bool available) {Unchanged: Header *header_new(Header *previous, size_t size, bool available) {
Unchanged: Header *header = sbrk(sizeof(Header) + size);Unchanged: Header *header = sbrk(sizeof(Header) + size);
Unchanged: header-&gt;previous = previous;Unchanged: header-&gt;previous = previous;
Unchanged: header-&gt;next = NULL;Unchanged: header-&gt;next = NULL;
Unchanged: header-&gt;size = size;Unchanged: header-&gt;size = size;
Unchanged: header-&gt;available = false;Unchanged: header-&gt;available = false;
Unchanged: return header;Unchanged: return header;
Unchanged: }Unchanged: }
Unchanged: void *abmalloc(size_t size) {Unchanged: void *abmalloc(size_t size) {
Unchanged: if (size == 0) {Unchanged: if (size == 0) {
Unchanged: return NULL;Unchanged: return NULL;
Unchanged: }Unchanged: }
Unchanged: if (first == NULL) {Unchanged: if (first == NULL) {
Unchanged: first = last = header_new(NULL, size, false);Unchanged: first = last = header_new(NULL, size, false);
Unchanged: return first + 1;Unchanged: return first + 1;
Unchanged: }Unchanged: }
Unchanged: Header *header = first;Unchanged: Header *header = first;
Unchanged: while (header != NULL) {Unchanged: while (header != NULL) {
Unchanged: if (header-&gt;available &amp;&amp; (header-&gt;size &gt;= size)) {Unchanged: if (header-&gt;available &amp;&amp; (header-&gt;size &gt;= size)) {
Unchanged: header-&gt;available = false;Unchanged: header-&gt;available = false;
Unchanged: return header + 1;Unchanged: return header + 1;
Unchanged: }Unchanged: }
Unchanged: header = header-&gt;next;Unchanged: header = header-&gt;next;
Unchanged: }Unchanged: }
Unchanged: last = header_new(last, size, false);Unchanged: last = header_new(last, size, false);
Unchanged: last-&gt;previous-&gt;next = last;Unchanged: last-&gt;previous-&gt;next = last;
Unchanged: return last + 1;Unchanged: return last + 1;
Unchanged: }Unchanged: }
Unchanged: void abfree(void *ptr) {Unchanged: void abfree(void *ptr) {
Unchanged: if (ptr == NULL) {Unchanged: if (ptr == NULL) {
Unchanged: return;Unchanged: return;
Unchanged: }Unchanged: }
Unchanged: Header *header = (Header*) ptr - 1;Unchanged: Header *header = (Header*) ptr - 1;
Unchanged: if (header == last) {Unchanged: if (header == last) {
Unchanged: while ((header-&gt;previous != NULL) &amp;&amp; header-&gt;previous- &gt;available) {Unchanged: while ((header-&gt;previous != NULL) &amp;&amp; header-&gt;previous- &gt;available) {
Unchanged: header = header-&gt;previous;Unchanged: header = header-&gt;previous;
Unchanged: }Unchanged: }
Unchanged: last = header-&gt;previous;Unchanged: last = header-&gt;previous;
Unchanged: if (last != NULL) {Unchanged: if (last != NULL) {
Unchanged: last-&gt;next = NULL;Unchanged: last-&gt;next = NULL;
Unchanged: } else {Unchanged: } else {
Unchanged: first = NULL;Unchanged: first = NULL;
Unchanged: }Unchanged: }
Unchanged: brk(header);Unchanged: brk(header);
Unchanged: } else {Unchanged: } else {
Unchanged: header-&gt;available = true;Unchanged: header-&gt;available = true;
Unchanged: }Unchanged: }
Unchanged: }</code></pre>Unchanged: }</code></pre>
Unchanged: <!-- /wp:code -->Unchanged: <!-- /wp:code -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Esta mudança nos permite economizar consideravelmente mais memória. Existem, contudo, problemas a resolver ainda. Por exemplo, considere o seguinte cenário: solicitamos a alocação de um bloco de memória de 8 bytes, e <code>abmalloc()</code> reaproveita um boco de, digamos, 1024 bytes. Há claramente um desperdício.</p>Unchanged: <p>Esta mudança nos permite economizar consideravelmente mais memória. Existem, contudo, problemas a resolver ainda. Por exemplo, considere o seguinte cenário: solicitamos a alocação de um bloco de memória de 8 bytes, e <code>abmalloc()</code> reaproveita um boco de, digamos, 1024 bytes. Há claramente um desperdício.</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->
Unchanged: <!-- wp:paragraph -->Unchanged: <!-- wp:paragraph -->
Unchanged: <p>Veremos como resolver isso no próximo <em>post</em>.</p>Unchanged: <p>Veremos como resolver isso no próximo <em>post</em>.</p>
Unchanged: <!-- /wp:paragraph -->Unchanged: <!-- /wp:paragraph -->

Note: Spaces may be added to comparison text to allow better line wrapping.

Post a Comment

Your email is never shared. Required fields are marked *

*
*