¿Alguna función para consultar el tamaño de un bloque asignado?

3 minutos de lectura

Me doy cuenta de que es probable que cualquier función de este tipo no sea estándar, pero está bien para mi caso de uso. Básicamente, necesito un método (incluso si solo está expuesto a través de la interfaz syscall() de glibc) al que puedo pasar un puntero (un puntero que fue devuelto por una llamada anterior a malloc()) que devuelve el tamaño del bloque el puntero apunta a. ¿Existe tal cosa?

  • Hemos hecho esto antes. dos veces creo Llega el enlace…

    – dmckee — gatito ex-moderador

    15 de septiembre de 2009 a las 17:53

  • stackoverflow.com/questions/232691/… y stackoverflow.com/questions/1208644/…

    – dmckee — gatito ex-moderador

    15 de septiembre de 2009 a las 17:56

  • Por cierto: encontré esos en mi búsqueda “[malloc] encontrar bloque de tamaño”.

    – dmckee — gatito ex-moderador

    15 de septiembre de 2009 a las 17:57

Que yo sepa, no existe tal función al menos en C90/C99. Algunos sistemas, en su mayoría libc, proporcionan funciones para obtener el tamaño asignado (por ejemplo, malloc_size() en Mac OS X), pero esto no es portátil y probablemente debería evitar usarlo en el mejor de los casos.

avatar de usuario
clifford

No es necesario utilizar funciones no estándar, no es difícil escribir su propio asignador con la funcionalidad necesaria.

Debe saber el tamaño cuando asigna el bloque, así que simplemente conserve esa información. En mi opinión, hay pocas situaciones en las que no conocería esa información, ya que, por definición, la sabía cuando se asignó. Sin embargo, si necesita dicha funcionalidad, puede hacerlo simplemente envolviendo malloc() y agregando el tamaño al bloque.

void* smalloc( size_t size )
{
    // allocate block with additional space for size
    void* blk = malloc( size + sizeof(size_t) ) ;

    // set the size
    *((size_t*)blk) = size ;

    // return pointer to block after size field (user block)
    return ((size_t*)blk) + 1 ;
}

void sfree( const void* blk )
{ 
    // Free from the size field address, not the user block
    free( ((const size_t*)blk) - 1 ) ;
}

size_t ssize( const void* blk )
{
    // Size is immediately before user block
    return *(((size_t*)blk) - 1) ;
}

Sobre el punto de Jim Buck; En algunos objetivos, es posible que se necesite un poco de movimiento para preservar la alineación necesaria. Algunos objetivos generarán código menos eficiente si la alineación no es óptima, otros provocarán un aborto. Así que ten cuidado con esta solución. ¡Personalmente desconfío de la necesidad de esta solución!

Quizás una solución sería usar una estructura de datos como una tabla hash con la dirección malloc como clave y el tamaño como contenido, y usando la misma técnica de envoltura, almacenar el tamaño por separado del bloque, a expensas o rendimiento, almacenamiento adicional y quizás algún límite finito de capacidad en términos de cantidad de bloques que se pueden administrar.

Independientemente de cómo lo haga, el punto fundamental sigue siendo válido: ajuste el servicio básico para proporcionar lo que necesita.

  • Observo que esto es más o menos idéntico a la solución de Emil H dada en el segundo enlace en el comentario de dmckee a la pregunta original. Sin embargo, como código comentado, tal vez todavía tenga mérito, así que lo dejé reposar.

    – Clifford

    15 de septiembre de 2009 a las 18:29

  • Esto rompe cualquier garantía de alineación que malloc podría brindarle en una plataforma en particular. Si, por ejemplo, está en una plataforma que garantiza una alineación de 8 bytes, este ejemplo de código ahora la convierte en una alineación de 4 bytes.

    – Jim Buck

    15 de septiembre de 2009 a las 18:42

  • Acordado. Se agregó una nota adicional sobre ese tema.

    – Clifford

    15 de septiembre de 2009 a las 19:59

_msize en plataformas Windows.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad