VinBR

LP 17/10/2011

Oct 27th, 2011
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.82 KB | None | 0 0
  1.  
  2. # # # # # # # # # # # # # #
  3. # Linguagens de Programação #
  4. # Prof. Fernando Pereira #
  5. # notasdogarcia.blog.com #
  6. # # # # # # # # # # # # # #
  7.  
  8. // Cheguei na metade da aula =/.
  9.  
  10. // Estamos falando de memória Heap alocada durante a execução de um programa.
  11.  
  12. Blocos Livres
  13. São blocos que possuem um número indicando seu tamanho, seguido de um ponteiro, seguido do espaço que está de fato "livre"
  14. Esse ponteiro que citei acima forma uma lista encadeada de blocos Livres.
  15. Seu bloco cabeça é apontado por uma variável "global" chamado FL.
  16. Cada ponteiro de cada bloco aponta para o inicio do próximo bloco livre.
  17.  
  18. Blocos Ocupados
  19. São blocos que possuem um número indicando seu tamanho, seguido do espaço que está reservado para uso do programa.
  20.  
  21. // Exemplos de funções de alocação e dealocação:
  22.  
  23. // Obs: variáveis com @ antes indicam que ela é um ponteiro.
  24. dealoca(@p)
  25. {
  26. // aux aponta para o tamanho do bloco alocado.
  27. @aux = p-1;
  28.  
  29. // A posição de p conterá o ponteiro para o próximo bloco livre.
  30. // Como se trata de uma inserção em uma lista encadeada, p apontará para FL
  31. *p = FL;
  32. // E FL apontará para o bloco atual.
  33. FL = aux;
  34. }
  35.  
  36. // O professor comentou que essa versão está um pouco incorreta, disse que no site podemos encontrar uma versão sem erros.
  37. aloca(int size)
  38. {
  39. @aux = FL;
  40.  
  41. // Abaixo eu procuro um bloco cujo tamanho possa conter o valor desejado de alocação.
  42. while(aux != NULL && *aux < size + 1)
  43. aux = *(aux + 1);
  44.  
  45. // nextFree aponta para o inicio do novo bloco livre, formado polo restante do bloco livre original.
  46. @nextFree = aux + size + 1;
  47.  
  48. // O tamanho desse novo bloco é dado pelo tamanho antigo - tamanho alocado - byte necessário para guardar o tamanho do bloco.
  49. *nextFree = *aux - size - 1;
  50.  
  51. // Na linha abaixo, eu copio o ponteiro "prox" do bloco original para o novo bloco.
  52. *(nextFree+1) = *(aux+1);
  53.  
  54. // Por fim a posição de inicio da lista de blocos livres deve ser alterado para apontar para este novo, bloco livre.
  55. // (pessoalmente eu achei essa a linha mais errada do código =P, mas como o professor disse se quiser o código bonitinho procure no site dele)
  56. FL = nextFree;
  57.  
  58. // Por fim prenche-se o tamanho total do bloco alocado na posição 0 desse bloco
  59. *aux = size + 1;
  60.  
  61. // E retorna-se a posição 1 desse bloco para uso do usuário.
  62. return aux+1;
  63. }
  64.  
  65. Basicamente:
  66. Todo bloco deve conter seu tamanho no primeiro byte.
  67. Para alocar um novo bloco de tamanho size eu encontro um que tenha tamanho suficiente e divido esse bloco entre uma parte livre e uma parte reservada para o usuário.
  68. A parte livre contém ainda um ponteiro para o próximo bloco livre, enquanto a parte do usuário contém apenas o tamanho do bloco.
  69.  
  70. E FL passa a apontar para o novo bloco livre que acabei de criar com essa divisão ( o q eu acho mto mto errado xP, posso ter copiado algo errado )
  71.  
  72. Por fim o ponteiro que eu retorno para o uso do usuário é o ponteiro do bloco +1 assim ele não tem acesso ao byte de tamanho do bloco.
  73. Garantindo que esse byte não será alterado e poderá ser usado pelo dealoca().
  74.  
  75. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  76.  
  77. CONCEITO:
  78. Coalessing é o ato de fundir dois blocos livres adjacentes para aproveitar melhor o espaço.
  79.  
  80. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  81.  
  82. Exemplo de heap com 6 posições:
  83.  
  84. // considere a posição mais abaixo a posição 0, e a mais acima a 5
  85.  
  86. livre
  87. livre
  88. livre
  89. livre
  90. @NULL
  91. 6 ( é para cá que aponta FL, ou seja a lista de blocos livres. )
  92.  
  93. Se eu alocar um arranjo de 3 palavras tenho:
  94.  
  95. @NULL
  96. 2 ( é para cá que aponta FL, ou seja a lista de blocos livres. )
  97. alocado
  98. alocado
  99. alocado ( é essa posição que é retornada pelo método de alocar. escondendo o número 4 que será usado pelo dealocar() )
  100. 4
  101.  
  102. Agora vou desalocar esse mesmo bloco e veja como ficará o heap:
  103.  
  104. @NULL
  105. 2
  106. livre
  107. livre
  108. @4 ( esse é o apontador que aponta para o próximo bloco livre )
  109. 4 ( é para cá que aponta FL, ou seja a lista de blocos livres. )
  110.  
  111. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  112.  
  113. // Nota solta:
  114. // Lista duplamente encadeada com um só ponteiro.
  115. cada posição guarda um xor entre o ponteiro antes e o ponteiro depois.
  116. xor é comultativo, e usa-se a posição "anterior" para se cálcular a posição prox.
  117.  
  118. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  119.  
  120. Coletor de lixo.
  121.  
  122. Quando eu aloco um bloco, além de reservar o espaço para o tamanho do bloco, eu aloco também um para o contador de referencia.
  123. Assim para cada ponteiro que for apontado para esse bloco, eu incremento esse contador, e para cada um que deixa de apontar, eu decremento.
  124.  
  125. Dessa forma um bloco com 0 referencias pode ser considerado um bloco livre, ou um bloco à ser liberado (ou seja incluso na lista FL).
  126.  
  127. Porém para isso funcionar eu preciso de identificar bem quando um ponteiro está sofrendo uma atribuição, para poder gerenciar os contadores de referencia.
  128. Em C e C++ isso é quase impossível e é por isso que não se usam coletores de lixo nessas linguagens.
  129. Porém o professor nos disse que existem coletores de lixo para C e C++, basta agente procurar.
  130.  
  131. Isso funciona sempre?
  132.  
  133. Suponha que eu tenho dois blocos de memória, onde cada um contém um ponteiro que referencia o outro bloco de memória.
  134. Assim mesmo que todos os outros ponteiros deixem de apontar para estes 2 ainda assim eles serão considerados como blocos alocados, pois ainda havera uma referencia.
  135. O que me faz perder espaço de memória desnecessáriamente.
  136.  
  137. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  138.  
  139. Outro coletor de lixo.
  140.  
  141. Outra forma mais segura de realizar a coleta de lixo é buscar recursivamente pela arvore de ponteiros contidos nos programa,
  142. // (Ou seja, partindo dos ponteiros declarados estaticamente encontrar os que foram declarados dinâmicamente e continuar recursivamente).
  143. e marcar todo ponteiro encontrado por esse processo com um "V" de "Verificado", ou algo assim.
  144.  
  145. Após isso basta caminhar pelo heap e desalocar qualquer ponteiro que não possua o V pois certamente ele não é alcançável pelo programa e é portanto dispensável.
  146.  
  147. A complexidade disso é da ordem de uma busca em grafo.
  148.  
  149. // fim da aula
Advertisement
Add Comment
Please, Sign In to add comment