¿Cuál es la diferencia entre xmalloc y malloc?

10 minutos de lectura

avatar de usuario
vaichidrewar

Cuál es la diferencia entre xmalloc() y malloc() para la asignación de memoria?
¿Hay alguna ventaja de usar xmalloc()?

  • malloc() existe en el estándar C. xmalloc() no. Donde está esto xmalloc() función definida?

    –Keith Thompson

    28 de septiembre de 2011 a las 22:16

  • Dónde viste esto xmalloc? Y la principal diferencia entre los dos es que malloc es parte del estándar C y xmalloc no es

    – Pretoriano

    28 de septiembre de 2011 a las 22:16


  • Aquí hay un ejemplo de xmalloc en uso: github.com/kanwei/algorithms/blob/…

    – película42

    22 de abril de 2015 a las 17:54

  • entonces @KeithThompson, ¿deberíamos usar malloc y no xmalloc() ? en caso afirmativo diga por qué?

    – Simón

    11 de marzo de 2020 a las 18:05

  • @simon Ver la respuesta aceptada. No tengo nada que agregar.

    –Keith Thompson

    11 de marzo de 2020 a las 18:40

avatar de usuario
orlp

xmalloc() es una función no estándar que tiene el lema triunfar o morir. Si no puede asignar memoria, terminará su programa e imprimirá un mensaje de error para stderr.

La asignación en sí no es diferente; solo el comportamiento en el caso de que no se pueda asignar memoria es diferente.

Usar malloc()ya que es más amigable y estándar.

  • Aprendí algo nuevo. ¡Gracias! solo explicaría xmalloc Y dejar las cosas así. O tal vez decir, usa lo que tenga sentido para tu situación. Por ejemplo, si estoy escribiendo un programa para un sistema operativo específico y no es de misión crítica que no me importe perder datos en OOM, xmalloc tiene sentido.

    – leyendas2k

    27 de diciembre de 2021 a las 9:38


xmalloc no es parte de la biblioteca estándar. Por lo general, es el nombre de una función muy dañina para los programadores perezosos que es común en muchos programas GNU, que llama abort si malloc falla Dependiendo del programa/biblioteca, también podría convertir malloc(0) dentro malloc(1) para asegurar eso xmalloc(0) devuelve un puntero único.

En todo caso, aborting en malloc La falla es un comportamiento muy, muy malo, especialmente para el código de la biblioteca. Uno de los ejemplos más infames es GMP (la biblioteca aritmética de multiprecisión de GNU), que aborta el programa de llamada cada vez que se queda sin memoria para un cálculo.

El código de nivel de biblioteca correcto siempre debe manejar las fallas de asignación revirtiendo cualquier operación parcialmente completada en el medio y devolviendo un código de error a la persona que llama. El programa que realiza la llamada puede decidir qué hacer, lo que probablemente implique guardar datos críticos.

  • Por supuesto, saving critical data y casi cualquier otra cosa que el programa de llamada pueda querer hacer también requiere la asignación de páginas de memoria (incluso si usted mismo no las asigna, las funciones de la biblioteca deben hacerlo). No creo que sea muy probable que puedas recuperarte en cualquier caso.

    – Frerich Raabe

    19 mayo 2014 a las 9:20

  • Si es así, lo estás haciendo mal. No hay una necesidad legítima de serialización para usar nuevas asignaciones.

    – R.. GitHub DEJA DE AYUDAR A ICE

    19 mayo 2014 a las 11:37

  • Llamar a los desarrolladores que usan xmalloc() ‘programadores perezosos’ es injusto. Detectar errores de asignación es no siempre es posible. ¿No es una pérdida de tiempo y dinero inflar su base de código con controles sobre el valor de retorno de malloc() si su sistema operativo de destino es uno en el que malloc() (esencialmente) nunca falla debido a la sobreasignación que está habilitada? Codificar un editor de niveles interno para un juego como si fuera un sistema de control de tráfico aéreo solo aumenta el costo sin ningún beneficio real. Fuera de los sistemas críticos para la seguridad, está bien ser ‘perezoso’ a veces, en mi humilde opinión.

    – evadir flujo

    13 de junio de 2014 a las 22:41

  • @evadeflow: dígale eso a la persona que pierde su documento debido a que abrió accidentalmente un segundo documento que es demasiado grande para caber en la memoria (le sucedió ayer a alguien que no me cree en este tema).

    – R.. GitHub DEJA DE AYUDAR A ICE

    13 de junio de 2014 a las 23:23

  • @evadeflow: ese es un enfoque válido a nivel de aplicación, pero no a nivel de biblioteca. No es razonable que una biblioteca (p. ej., simplista) suponga que la aplicación que realiza la llamada no tiene ningún dato no registrado que no le importe perder. Y si una biblioteca se va a comportar de esta manera, debe documentar ese requisito de manera destacada en lugar de ocultarlo en la documentación de las funciones de asignación. Por supuesto que no harán eso, porque nadie usaría a sabiendas una biblioteca documentada como tal; para que la gente use una biblioteca de tan baja calidad, debe ocultar el problema.

    – R.. GitHub DEJA DE AYUDAR A ICE

    16 de junio de 2014 a las 17:04


avatar de usuario
evadir flujo

Como otros han mencionado, es cierto que xmalloc se implementa muy a menudo como una función contenedora que invoca el sistema operativo proporcionado malloc y ciegamente llama abort o exit si falla. Sin embargo, muchos Los proyectos contienen un xmalloc función que intenta guardar el estado de la aplicación antes de salir (ver, por ejemplo, neovim).

Personalmente, pienso en xmalloc como una especie de proyecto específico extendido malloc en lugar de un saliendo malloc. Aunque no recuerdo haber visto nunca una versión que no terminar llamando abort o exitalgunos de ellos hacen un lote más que eso.

Así que la respuesta a la pregunta “¿Cuál es la diferencia entre xmalloc y malloc es: depende. xmalloc es una función específica del proyecto no estándar, por lo que podría hacer cualquier cosa. La única forma de saberlo con seguridad es leer el código.

avatar de usuario
Ciro Santilli Путлер Капут 六四事

xmalloc es parte de la libertad

https://gcc.gnu.org/onlinedocs/libiberty/index.html que es una biblioteca de utilidades GNU.

malloc es ANSI C.

xmalloc a menudo se incluye en la fuente en muchos proyectos importantes de GNU, incluidos GCC y Binutils, los cuales lo usan mucho. Pero también es posible construirlo como una biblioteca dinámica para usar en sus programas. Por ejemplo, Ubuntu tiene el libiberty-dev paquete.

xmalloc está documentado en: https://gcc.gnu.org/onlinedocs/libiberty/Functions.html y en GCC 5.2.0 se implementa en libiberty/xmalloc.c

PTR
xmalloc (size_t size)
{
  PTR newmem;

  if (size == 0)
    size = 1;
  newmem = malloc (size);
  if (!newmem)
    xmalloc_failed (size);

  return (newmem);
}

void
xmalloc_failed (size_t size)
{
#ifdef HAVE_SBRK
  extern char **environ;
  size_t allocated;

  if (first_break != NULL)
    allocated = (char *) sbrk (0) - first_break;
  else
    allocated = (char *) sbrk (0) - (char *) &environ;
  fprintf (stderr,
       "\n%s%sout of memory allocating %lu bytes after a total of %lu bytes\n",
       name, *name ? ": " : "",
       (unsigned long) size, (unsigned long) allocated);
#else /* HAVE_SBRK */
  fprintf (stderr,
       "\n%s%sout of memory allocating %lu bytes\n",
       name, *name ? ": " : "",
       (unsigned long) size);
#endif /* HAVE_SBRK */
  xexit (1);
}

/* This variable is set by xatexit if it is called.  This way, xmalloc
   doesn't drag xatexit into the link.  */
void (*_xexit_cleanup) (void);

void
xexit (int code)
{
  if (_xexit_cleanup != NULL)
    (*_xexit_cleanup) ();
  exit (code);
}

Lo cual, como otros mencionaron, es bastante sencillo:

  • probar malloc
  • si falla
    • imprimir mensajes de error
    • llamar exit

un ejemplo primitivo de xmalloc.c en K&R C

#include <stdio.h>
extern char *malloc ();
void *
xmalloc (size)
    unsigned size;
{
  void *new_mem = (void *) malloc (size);
  if (new_mem == NULL)    
    {
      fprintf (stderr, "fatal: memory exhausted (xmalloc of %u bytes).\n", size);
      exit (-1);
    }
  return new_mem;
}

luego en el encabezado de tu código (antes) pones

#define malloc(m) xmalloc(m)

para reescribir silenciosamente la fuente antes de la compilación. (Puede ver el código reescrito invocando el preprocesador C directamente y guardando la salida).

si fallar su programa no es lo que quiere, puede hacer algo diferente

  • Usa un recolector de basura
  • rediseñe su código para que consuma menos memoria
  • tiene un código de verificación de errores en su programa para manejar correctamente una falta de memoria u otro error de asignación.

A los usuarios no les gusta perder sus datos debido a un comando de bloqueo incorporado en su programa.

  • @MilesRout: es K&R C, cosas muy antiguas.

    – orlp

    04/02/2013 a las 20:25

  • +1, pero la recolección de basura y C probablemente no vayan muy bien juntas.

    – gracias

    13 de diciembre de 2016 a las 14:17


  • @thb En aplicaciones especializadas podría ser bueno. Claro, no funcionará para todo, pero hay cosas en las que funciona bien. TAMBIÉN… Bueno, la recolección de basura en el tiempo de ejecución de un idioma es la recolección de basura en C, ya que el propio tiempo de ejecución está escrito en C.

    –Paul Stelian

    3 abr 2019 a las 16:29

avatar de usuario
MaxPowers

He visto xmalloc mientras trabajaba en IBM AIX. xmalloc es un servicio de kernel proporcionado por AIX.

En mi opinión, nada puede explicar mejor una función que la página del manual de la función. Así que estoy pegando los detalles a continuación de la página del manual

Propósito: Asigna memoria.

Sintaxis:

caddr_t xmalloc (tamaño, alineación, montón)

Parámetros:

tamaño: especifica el número de bytes a asignar.

align: especifica las características de alineación para la memoria asignada.

montón: especifica la dirección del montón desde el que se asignará la memoria.

Descripción:

El servicio del kernel xmalloc asigna un área de memoria fuera del montón especificado por el parámetro de montón. Esta área es el número de bytes de longitud especificado por el parámetro de tamaño y se alinea en el límite de bytes especificado por el parámetro de alineación. El parámetro de alineación es en realidad la base logarítmica 2 del límite de dirección deseado. Por ejemplo, un valor de alineación de 4 solicita que el área asignada se alinee en un límite de 2^4 (16) bytes.

Hay varios montones proporcionados por el kernel para que los usen las extensiones del kernel. Dos montones de kernel primarios son kernel_heap y pinned_heap. Las extensiones de kernel deben usar el valor kernel_heap cuando asignan memoria que no está anclada, y deben usar el valor pinned_heap cuando asignan memoria que siempre debe estar anclada o anclada durante largos períodos de tiempo. Cuando se asigna desde el montón pinned_heap, el servicio del kernel xmalloc fijará la memoria antes de una devolución exitosa. Los servicios de anclaje y desbloqueo del kernel se deben usar para fijar y desbloquear la memoria del montón kernel_heap cuando la memoria solo se debe fijar durante un período de tiempo limitado. La memoria del montón kernel_heap se debe desanclar antes de liberarla. La memoria del montón pinned_heap no se debe desanclar.

Si uno está interesado en saber más sobre esta función puede visitar el siguiente enlace:
Soporte de IBM AIX

  • @MilesRout: es K&R C, cosas muy antiguas.

    – orlp

    04/02/2013 a las 20:25

  • +1, pero la recolección de basura y C probablemente no vayan muy bien juntas.

    – gracias

    13 de diciembre de 2016 a las 14:17


  • @thb En aplicaciones especializadas podría ser bueno. Claro, no funcionará para todo, pero hay cosas en las que funciona bien. TAMBIÉN… Bueno, la recolección de basura en el tiempo de ejecución de un idioma es la recolección de basura en C, ya que el propio tiempo de ejecución está escrito en C.

    –Paul Stelian

    3 abr 2019 a las 16:29

¿Ha sido útil esta solución?