La implementación de mi cola (en C) [v.2] -- ampo con queue camp codereview Relacionados El problema

My queue implementation (in C) [V.2]


7
vote

problema

Español

Mi implementación anterior: Mi cola Implementación (en C)

Reescribí la cola siguiendo las sugerencias de @ VNP. Aquí está la segunda versión de él: Se aprecian cualquier sugerencia o consejos :) (Incluso consejos sobre el código de espaciado / nombramiento)

(el cliente debe malloc () los datos necesarios para insertarse en la cola, y deben proporcionar dtor () mientras destruyen la cola)

  #include <stdlib.h> /* malloc(), EXIT_SUCCESS */ #include <stdio.h> /* fprintf(), printf() */ #include <stddef.h> /* size_t */ #include <assert.h> /* assert() */  struct Queue_node {     struct Queue_node *next;     void *data; };  struct Queue {     struct Queue_node *front;     struct Queue_node *back;      size_t size; };  struct Queue* create_queue(void) {      struct Queue *created_queue = malloc(sizeof(*created_queue));      if (created_queue == NULL) { // if malloc() failed         return NULL;     }      created_queue->front = NULL;     created_queue->back = NULL;     created_queue->size = 0; // an empty queue      return created_queue; }  struct Queue* destroy_queue(struct Queue *input_queue, void (*data_dtor)(void*)) { // (pointer arg) to force l-value      while (input_queue->front != NULL) {          struct Queue_node *deleted_node = input_queue->front;         input_queue->front = input_queue->front->next;          if (data_dtor != NULL) {             data_dtor(deleted_node->data);         }         free(deleted_node);     }     free(input_queue); }  void queue_push(struct Queue *input_queue, void *input_data) {      struct Queue_node *input_node = malloc(sizeof(*input_node));     if (input_node == NULL) {         fprintf(stderr, "malloc() failed in queue_push() ");     }     input_node->next = NULL;     input_node->data = input_data;      if (input_queue->front == NULL) { // first insert         assert(input_queue->back == NULL);         assert(input_queue->size == 0);         input_queue->front = input_node;     }     else {         assert(input_queue->back != NULL);         assert(input_queue->size > 0);         input_queue->back->next = input_node;     }     input_queue->back = input_node;      ++input_queue->size; }  void* queue_pop(struct Queue *input_queue) {      if (input_queue->front == NULL) {         assert(input_queue->back == NULL);         assert(input_queue->size == 0);         return NULL;     }      assert(input_queue->front != NULL);     assert(input_queue->back != NULL);     assert(input_queue->size > 0);      --input_queue->size;      struct Queue_node *deleted_node = input_queue->front;     input_queue->front = input_queue->front->next;      void *return_data = deleted_node->data;     free(deleted_node);      return return_data; }  /*---- dtor written by client -----*/  void dtor(void *data) {     printf("DTOR: %i destroyed ", *((int*)data));     free(data); }  /*---------------------------------*/  int main() {      struct Queue *my_queue = create_queue();     if (my_queue == NULL) {         fprintf(stderr, "malloc() failed in create_queue() ");     }     // ^ creates queue      for (int i = 0; i < 10; ++i) {          int *my_node = malloc(sizeof(int));         *my_node = i;         queue_push(my_queue, my_node);     }     // ^ appends 10 nodes      for (int i = 0; i < 8; ++i) {          int *my_data = queue_pop(my_queue);         printf("POP: %i popped ", *my_data);         free(my_data);     }     // ^ pops and displays 8 nodes      destroy_queue(my_queue, dtor);     // ^ destroys the queue      return EXIT_SUCCESS; }   

Da la salida:

  POP: 0 popped POP: 1 popped POP: 2 popped POP: 3 popped POP: 4 popped POP: 5 popped POP: 6 popped POP: 7 popped DTOR: 8 destroyed DTOR: 9 destroyed   

Se aprecian cualquier sugerencia o consejo :)

(incluso consejos sobre el código de espacios / nombres)

Editar: Hay un error en el código. El tipo de retorno de destroy_queue debe ser vacío y no cola de estructura. También en la función Queue_POP, necesitamos volver a volver a null cuando el frente es NULL. De lo contrario, tratando de abrir una cola vacía causa afirmación.

Original en ingles

My previous implementation: My queue implementation (in C)

I rewrote the queue following @vnp's suggestions. Here is the second version of it: Any suggestions or tips are appreciated :) (even tips about spacing/naming code)

(The client must malloc() the data needed to be inserted into the queue, and must provide dtor() while destroying the queue)

#include <stdlib.h> /* malloc(), EXIT_SUCCESS */ #include <stdio.h> /* fprintf(), printf() */ #include <stddef.h> /* size_t */ #include <assert.h> /* assert() */  struct Queue_node {     struct Queue_node *next;     void *data; };  struct Queue {     struct Queue_node *front;     struct Queue_node *back;      size_t size; };  struct Queue* create_queue(void) {      struct Queue *created_queue = malloc(sizeof(*created_queue));      if (created_queue == NULL) { // if malloc() failed         return NULL;     }      created_queue->front = NULL;     created_queue->back = NULL;     created_queue->size = 0; // an empty queue      return created_queue; }  struct Queue* destroy_queue(struct Queue *input_queue, void (*data_dtor)(void*)) { // (pointer arg) to force l-value      while (input_queue->front != NULL) {          struct Queue_node *deleted_node = input_queue->front;         input_queue->front = input_queue->front->next;          if (data_dtor != NULL) {             data_dtor(deleted_node->data);         }         free(deleted_node);     }     free(input_queue); }  void queue_push(struct Queue *input_queue, void *input_data) {      struct Queue_node *input_node = malloc(sizeof(*input_node));     if (input_node == NULL) {         fprintf(stderr, "malloc() failed in queue_push()\n");     }     input_node->next = NULL;     input_node->data = input_data;      if (input_queue->front == NULL) { // first insert         assert(input_queue->back == NULL);         assert(input_queue->size == 0);         input_queue->front = input_node;     }     else {         assert(input_queue->back != NULL);         assert(input_queue->size > 0);         input_queue->back->next = input_node;     }     input_queue->back = input_node;      ++input_queue->size; }  void* queue_pop(struct Queue *input_queue) {      if (input_queue->front == NULL) {         assert(input_queue->back == NULL);         assert(input_queue->size == 0);         return NULL;     }      assert(input_queue->front != NULL);     assert(input_queue->back != NULL);     assert(input_queue->size > 0);      --input_queue->size;      struct Queue_node *deleted_node = input_queue->front;     input_queue->front = input_queue->front->next;      void *return_data = deleted_node->data;     free(deleted_node);      return return_data; }  /*---- dtor written by client -----*/  void dtor(void *data) {     printf("DTOR: %i destroyed\n", *((int*)data));     free(data); }  /*---------------------------------*/  int main() {      struct Queue *my_queue = create_queue();     if (my_queue == NULL) {         fprintf(stderr, "malloc() failed in create_queue()\n");     }     // ^ creates queue      for (int i = 0; i < 10; ++i) {          int *my_node = malloc(sizeof(int));         *my_node = i;         queue_push(my_queue, my_node);     }     // ^ appends 10 nodes      for (int i = 0; i < 8; ++i) {          int *my_data = queue_pop(my_queue);         printf("POP: %i popped\n", *my_data);         free(my_data);     }     // ^ pops and displays 8 nodes      destroy_queue(my_queue, dtor);     // ^ destroys the queue      return EXIT_SUCCESS; } 

It gives the output:

POP: 0 popped POP: 1 popped POP: 2 popped POP: 3 popped POP: 4 popped POP: 5 popped POP: 6 popped POP: 7 popped DTOR: 8 destroyed DTOR: 9 destroyed 

Any suggestions or tips are appreciated :)

(even tips about spacing/naming code)

Edit: There is a mistake in the code. Return type of destroy_queue must be void and not struct Queue. Also in the queue_pop function, we need to set back to NULL when front is NULL. Otherwise trying to pop an empty queue causes assert.

     
       
       

Lista de respuestas

2
 
vote

Una cosa que haría diferente es crear un Queue_Alloc_Item para que pueda decidir usar malloc u otro administrador de memoria en el futuro.

tienes:

  int *my_node = malloc(sizeof(int));   

para ints que siempre usa malloc. Cuando ya hay clientes que utilizan esto y encuentras una mejor manera de reemplazar al administrador de memoria para objetos pequeños, ya no puedes cambiar esto

 

One thing that I would do different is create a queue_alloc_item so you can decide to use malloc or another memory manager in the future.

You have:

int *my_node = malloc(sizeof(int)); 

for ints which always uses malloc. When there are clients using this already and you find a better way to replace the memory manager for small objects you can't change this anymore

 
 
       
       

Relacionados problema

3  Cola MultiPhread Generic Simple  ( Simple generic multithreaded queue ) 
Esta es una cola de hilo simple que se usa en un modelo de consumidor productor. public class ThreadedQueue<TType> { private Queue<TType> _queue; p...

4  Linkedlist para ser utilizado en una pila o cola  ( Linkedlist to be used in a stack or queue ) 
Todo esto funciona. Solo quería asegurarse de que no me perdí nada. Viniendo de C ++ y trabajando en mi camino a través de algoritmos, 4ta ed. Aquí está mi cl...

2  Cola de bloqueo delimitada  ( Bounded blocking queue ) 
¿Puede alguien por favor revise este código para mí? No he implementado todos los métodos para la simplicidad. NSUSerDefaults1 Preguntas abiertas: l...

2  Implementación de la lista de la cola prioritaria  ( Priority queue linked list implementation ) 
Soy nuevo en Python y quería asegurarme de que mi código responde a la pregunta de mi tarea debido. Mi tarea: Una cola de prioridad es una cola en la que...

8  Reader de cola sin bloqueo Seclador de Singler-Writer en C ++  ( Lockless queue multiple reader singler writer in c ) 
Escribí una cola sin encimera para enviar objetos pequeños desde un solo hilo a un hilo de trabajador aleatorio. suposiciones: x86 / x86_64 compilado con...

19  Una clase de hilo-piscina / cola personalizada  ( A custom thread pool queue class ) 
Quería una clase que ejecuta cualquier cantidad de tareas, pero solo cierta cantidad al mismo tiempo (por ejemplo, para descargar varios contenidos de Interne...

5  Cola de bloqueo con la exactitud de la lista doblemente vinculada  ( Lock free queue with doubly linked list correctness ) 
Necesito una cola de bloqueo que se implementa mediante la lista doblemente vinculada. es mi código correcto? ¿Hay algún error? ¿Hay alguna mejoras a realiz...

3  Cola de JavaScript para las funciones de ASYNC  ( Javascript queue for async functions ) 
Basado en la respuesta a Mi pregunta anterior sobre el desbordamiento de pila , armé la siguiente clase de cola. Me doy cuenta de que ya hay bibliotecas para...

1  DEQUEUE () en la implementación de la cola que utiliza una lista circular vinculada  ( Dequeue in queue implememtation that uses a circular linked list ) 
Utilizo una lista de enlaces circulares para implementar un queue , y solo sostiene un 99887776665544332 (Tenga en cuenta que 99887776655443333 enlaces a...

2  Montón Binomial en Java  ( Binomial heap in java ) 
Tengo esta implementación de un montón de binomio que proporciona inserto, disminución de la tecla y el extracto en el tiempo logarítmico. minpriorityqueue...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos