Marta Santos
-
Postagens
9 -
Registro em
-
Última visita
Tipo de Conteúdo
Fóruns
Treinamentos
Notícias
Artigos
Contribuindo
Profissões
Materiais de estudo
Pesquisa
Downloads
Loja
Eventos
Blogs
Galeria
Posts postados por Marta Santos
-
-
14 minutes ago, Felipe.Silva said:
void *myMalloc(size_t size) { // TODO t_block b; if(head){ tail = head; // ....
Esse "tail = head" não me parece certo. Pela lógica do código tail deveria ser atualizado para o novo bloco alocado na memória toda vez que a função extend_heap() precisar ser chamada... Do jeito que está tail volta a apontar para head a cada nova chamada de myMalloc() (exceto a primeira chamada onde head ainda será NULL).
Sugiro atualizar o código para as vezes que precisou chamar "b = extend_heap(size);" atualizar tail para apontar para b.
Ah, e qual é a lógica do else dentro da função myFree()? Também toma cuidado com a diferença entre = e ==. Dentro do if deveria ser == certo?
Outra coisa que não entendi é isso: b = tail->next = NULL;
Você quer modificar b para NULL? Mas logo em seguida você executa brk(b); o que não faria sentido passar NULL para esta função.
E b também não é inicializada caso o head não seja NULL, pois você declarou a variável mas só a inicializar dentro do if.Essa estrutura s_block foi o professor que passou assim? Pois eu vejo um probleminha ao precisar desalocar memória e atualizar o valor de tail. Como você vai pegar o endereço do penúltimo bloco sem um ponteiro para o bloco anterior?
Até daria para percorrer a lista para isso, mas seria mais eficiente ter um ponteiro t_block previous na estrutura. ?Ah, uma dica: Antes de mais nada sugiro implementar logo a função debugBlockList(). Ela vai te ajudar a "visualizar" a lista e assim ficará mais fácil entender o que está funcionando conforme deveria e o que não está.
Olá,
Entretanto atualizei as funções e ficou assim...
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #define BLOCK_SIZE sizeof(struct s_block) typedef struct s_block *t_block; struct s_block { size_t size; // current size of block t_block next; // pointer to next block int free; // flag indicating that the block is free or occupied; 0 or 1. }; t_block head = NULL; // points to the beginning of the list t_block tail = NULL; // points to the last element of the list t_block find_block(size_t size) { t_block b = head; // TODO: alterar para best-fit while (b!=NULL && !(b->free && b->size >= size)){ b = b->next; } return b; } t_block extend_heap(size_t s) { t_block b = (t_block) sbrk(BLOCK_SIZE+s); if (b == (void *)-1) return NULL; /* if sbrk fails, return NULL pointer*/ b->size = s; b->next = NULL; b->free = 0; if (head==NULL) head = b; else tail->next = b; tail = b; return b; // with metadata } void debugBlockList() { t_block p = head; printf("current block list:\n"); while(p!=NULL){ printf("address: %lu - %u bytes (%s)\n", (unsigned long)(p), p->size, p->free?"free":"in use"); p=p->next; } } void *myMalloc(size_t size) { t_block b = find_block(size); if(b) { b->free = 0; } else { b = extend_heap(size); if(!b) return NULL; } return(b+1); } void myFree(void *ptr) { t_block b = (t_block)ptr - 1; b -> free = 1; }
Acho que ficou bem, mas agora tenho que fazer uma implementação best-fit para o find_block
-
18 minutes ago, Fernando Mercês said:
Código interessante! Acho que o @Felipe.Silva vai curtir também! Ele publicou um artigo recentemente sobre alocação de memória aqui no Mente Binária. ?
Marta, ao que me parece, sua myFree() não está funcionando. Criei uma main() básica:
int main(void) { int *p = myMalloc(sizeof(int)); scanf("%d", p); printf("Before freeing it: %d\n", *p); myFree(p); printf("After freeing it: %d\n", *p); return 0; }
E o conteúdo de p é impresso na tela, mesmo depois da chamada à myFree():
% ./marta <<< 42 Before freeing it: 42 After freeing it: 42
Em que momento você recebe um runtime error?
Abraço,
Fernando
Olá Fernando!
Ao que parece não era necessário implementar o código todo que mandei no inicio...
Foi-me dado o seguinte código:
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #define BLOCK_SIZE sizeof(struct s_block) typedef struct s_block *t_block; struct s_block { size_t size; // current size of block t_block next; // pointer to next block int free; // flag indicating that the block is free or occupied; 0 or 1. }; t_block head = NULL; // points to the beginning of the list t_block tail = NULL; // points to the last element of the list t_block find_block(size_t size) { t_block b = head; // TODO: alterar para best-fit while (b!=NULL && !(b->free && b->size >= size)) b = b->next; return b; } t_block extend_heap(size_t s) { t_block b = sbrk(BLOCK_SIZE+s); if (b == (void *)-1) return NULL; /* if sbrk fails, return NULL pointer*/ b->size = s; b->next = NULL; b->free = 0; if (head==NULL) head = b; else tail->next = b; tail = b; return b; // with metadata } void debugBlockList() { t_block p = head; printf("current block list:\n"); // TODO printf("address: %lu - %u bytes (%s)\n", (unsigned long)(p), p->size, p->free?"free":"in use"); } void *myMalloc(size_t size) { // TODO } void myFree(void *ptr) { // TODO } /** * teste myMalloc/myFree **/ int main(int argc, char *argv[]) { unsigned int maxSpace; if (argc != 2) { printf("%s max_memory_to_allocate\n", argv[0]); exit(1); } maxSpace = atoi(argv[1]); printf("Metadata size=%d\n", BLOCK_SIZE); // getting the current break value printf("Current program break = %lu\n", (unsigned long)sbrk(0)); for (int s = 1; s < maxSpace; s *= 2) { void *ptr = myMalloc(s); if (ptr == NULL) printf("No more mem\n"); else printf("returned pointer = %lu\n", (unsigned long)ptr); myFree(ptr); } debugBlockList(); // getting the current break value printf("Current program break = %lu\n", (unsigned long)sbrk(0)); for (int s = maxSpace; s>0; s /= 2) { void *ptr = myMalloc(s); if (ptr == NULL) printf("No more mem\n"); else printf("returned pointer = %lu\n", (unsigned long)ptr); } debugBlockList(); return 0; }
(onde está #TODO é o que tenho que fazer)
Só posso implementar a função malloc e a função free com as funções já disponobilizadas - find_block / extend_heap. Não tinha percebido isso.
Até agora, tenho o seguinte:
void *myMalloc(size_t size) { // TODO t_block b; if(head){ tail = head; b = find_block(size); if(b) { b->free=0; } else { b = extend_heap(size); if(!b) return (NULL); } } else { b = extend_heap(size); if(!b) { return (NULL); } head = b; } return(b+1); } /* Get the block from and addr */ t_block get_block (void *p){ char *tmp; tmp = p; return(p = tmp -= BLOCK_SIZE); } /* Valid addr for free */ int valid_addr (void *p){ if(head) { if(p>head && p<sbrk(0)) { return (p == (get_block(p))); } } return (0); } void myFree(void *ptr) { // TODO t_block b; if(valid_addr(ptr)){ b = get_block(ptr); b->free=1; } else { if(b=tail) b = tail->next = NULL; else head = NULL; brk(b); } }
Acho que o problema está no myFree, mas não estou a conseguir perceber o que está mal nem como implementar esta função sem usar as funções get_block e valid_addr....
Alguma dica????
-
boa tarde, tenho um exercicio onde preciso implementar a função void *myMalloc(unsigned int bytesToAllocate) e a função int myFree(void *address). Tenho também que implementar void debugBlockList() para mostrar todo o conteúdo da lista de blocos.
Até agora fiz o que está no código em baixo, mas estou com RUNTIME ERROR em alguns testes de verificação do código noutros o output que me dá não é o correto...
Alguém me podia ajudar????
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #define BLOCK_SIZE 12 //sizeof(struct s_block) #define align4(x) (((((x)-1)>>2)>>2)) typedef struct s_block *t_block; struct s_block { size_t size; // current size of block t_block next; // pointer to next block t_block prev; int free; // flag indicating that the block is free or occupied; 0 or 1. void *ptr; char data[1]; }; t_block head = NULL; // points to the beginning of the list t_block tail = NULL; // points to the last element of the list t_block find_block(t_block *last, size_t size) { t_block b = head; while (b && !(b->free && b->size >= size)){ *last = b; b = b->next; } return b; } t_block extend_heap(t_block last, size_t s) { int sb; t_block b; b = sbrk (0); sb = (int)sbrk( BLOCK_SIZE + s); if (sb < 0) return (NULL ); b->size = s; b->next = NULL; b->prev = last; b->ptr = b->data; if (last) last ->next = b; b->free = 0; return (b); } /* Get the block from and addr */ t_block get_block (void *p) { char *tmp; tmp = p; return (p = tmp -= BLOCK_SIZE ); } /* Valid addr for free */ int valid_addr (void *p) { if (head) { if ((t_block)p>head && p<sbrk(0)) { return (p == ( get_block(p))->ptr ); } } return (0); } void split_block(t_block b, size_t s){ t_block new; new = (t_block )(b->data + s); new ->size = b->size - s - BLOCK_SIZE ; new ->next = b->next; new ->prev = b; new ->free = 1; new -> ptr = new->data; b->size = s; b->next = new; if(new->next) new->next->prev = new; } t_block fusion(t_block b){ if (b->next && b->next ->free ){ b->size += BLOCK_SIZE + b->next ->size; b->next = b->next ->next; if (b->next) b->next ->prev = b; } return (b); } void debugBlockList() { t_block p = head; printf("current block list:\n"); while(p!=NULL){ printf("address: %lu - %u bytes (%s)\n", (unsigned long)(p), p->size, p->free?"free":"in use"); p=p->next; } } void *myMalloc(size_t size) { t_block b,last; size_t s = align4(size); if(head) { last = head; b = find_block(&last,s); if(b) { /* can we split */ if ((b->size - s) >= ( BLOCK_SIZE + 4)) split_block(b,s); b->free =0; } else { /* No fitting block , extend the heap */ b = extend_heap(last ,s); if (!b) return(NULL ); } } else { /* first time */ b = extend_heap(NULL ,s); if (!b) return(NULL ); head = b; } return(b); } void myFree(void *ptr) { t_block b; if ( valid_addr (ptr)) { b = get_block (ptr); b->free = 1; /* fusion with previous if possible */ if(b->prev && b->prev ->free) b = fusion(b->prev ); /* then fusion with next */ if (b->next) fusion(b); else { /* free the end of the heap */ if (b->prev) b->prev ->next = NULL; else /* No more block !*/ head = NULL; brk(b); } } }
-
Boa tarde, tenho um método para fazer em linguagem java que calcule a média ponderada de notas de alunos numa certa questão. Essa questão pode estar inserida em vários testes e por isso ter várias classificações e diferentes números de alunos que responderam.
Exemplo:
Uma pergunta respondida por 10 alunos, com uma classificação média de 0.80 (80%) num teste e foi também respondida por 20 alunos, noutro teste, com uma classificação média de 0.75 (75%)
- Média ponderada: (0.80*10 + 0.75*20) / (10+20) = 0.77 (= 0.76666)
Se adicionarmos um 3º grupo de 15 alunos, com uma classificação média de 0.60
- a média ponderada fica (0.80*10 + 0.75*20 + 0.60*15) / (10+20+15) = 0.71 (= 0.7111111)
A minha dúvida é como guardar esses valores todos, de modo a ir buscar sempre os valores antigos quando um grupo novo com uma classificação nova é inserido.
Alguém pode ajudar?
Obrigada.
Função malloc e função free
em C/C++
Postado
Eu atualizei a minha resposta anterior porque recebi um email do meu professor a indicar que provavelmente o que falta é a implementação best-fit do find_block
Não é necessário atualizar tail nem head porque os blocos são atualizados no extend_heap.