vectores reservar que memoria dinamica crear con como arreglo array administracion c memory dynamic size allocation

reservar - que es la memoria dinamica en c



Determine el tamaño de la memoria asignada dinámicamente en C (15)

¿Hay alguna forma en C para averiguar el tamaño de la memoria asignada dinámicamente?

Por ejemplo, después

char* p = malloc (100);

¿Hay alguna manera de averiguar el tamaño de la memoria asociada con p ?


Bueno, ahora sé que esto no responde a tu pregunta específica, sin embargo, pensar fuera de la caja, por así decirlo ... Se me ocurre que probablemente no necesites saberlo. Ok, vale, no, no me refiero a que tengas una implementación mala o poco ortodoxa ... quiero decir es que probablemente (sin mirar tu código solo estoy adivinando) probablemente quieras saber si tus datos pueden caber en la memoria asignada, si ese es el caso, entonces esta solución podría ser mejor. No debería ofrecer demasiada sobrecarga y resolverá su problema de "ajuste" si eso es realmente lo que está manipulando:

if ( p != (tmp = realloc(p, required_size)) ) p = tmp;

o si necesita mantener los contenidos anteriores:

if ( p != (tmp = realloc(p, required_size)) ) memcpy(tmp, p = tmp, required_size);

por supuesto, podrías usar:

p = realloc(p, required_size);

y termine con esto.


Como todos los demás ya dijeron: No, no hay.

Además, siempre evitaría todas las funciones específicas del proveedor aquí, porque cuando encuentre que realmente necesita usarlas, eso generalmente es una señal de que lo está haciendo mal. Debe almacenar el tamaño por separado, o no tener que saberlo en absoluto. Usar las funciones del proveedor es la forma más rápida de perder uno de los principales beneficios de escribir en C, la portabilidad.


Esperaría que esto sea dependiente de la implementación.
Si obtuviste la estructura de datos del encabezado, podrías devolverla al puntero y obtener el tamaño.


Esta es la mejor manera que he visto para crear un puntero etiquetado para almacenar el tamaño con la dirección. Todas las funciones del puntero seguirían funcionando como se esperaba:

Robado de: https://.com/a/35326444/638848

También podría implementar un contenedor para malloc y agregar etiquetas gratis (como el tamaño asignado y otra metainformación) antes de que Malloc devuelva el puntero. Este es, de hecho, el método que un compilador de C ++ etiqueta objetos con referencias a clases virtuales. Aquí hay un ejemplo de trabajo:

#include <stdlib.h> #include <stdio.h> void * my_malloc(size_t s) { size_t * ret = malloc(sizeof(size_t) + s); *ret = s; return &ret[1]; } void my_free(void * ptr) { free( (size_t*)ptr - 1); } size_t allocated_size(void * ptr) { return ((size_t*)ptr)[-1]; } int main(int argc, const char ** argv) { int * array = my_malloc(sizeof(int) * 3); printf("%u/n", allocated_size(array)); my_free(array); return 0; }

La ventaja de este método sobre una estructura con tamaño y puntero

struct pointer { size_t size; void *p; };

es que solo necesita reemplazar el malloc y las llamadas gratuitas. Todas las demás operaciones de puntero no requieren refactorización.


Este código probablemente funcione en la mayoría de las instalaciones de Windows:

template <class T> int get_allocated_bytes(T* ptr) { return *((int*)ptr-4); } template <class T> int get_allocated_elements(T* ptr) { return get_allocated_bytes(ptr)/sizeof(T); }


Esto puede funcionar, una pequeña actualización en tu código:

void* inc = (void*) (++p) size=p-inc;

Pero esto dará como resultado 1, es decir, memoria asociada con p si es char* . Si es int* , el resultado será 4.

No hay forma de averiguar la asignación total.


La mentalidad C es proporcionar al programador herramientas para ayudarlo con su trabajo, no para proporcionar abstracciones que cambien la naturaleza de su trabajo. C también trata de evitar que las cosas sean más fáciles / seguras si esto sucede a expensas del límite de rendimiento.

Ciertas cosas que le gustaría hacer con una región de memoria solo requieren la ubicación del inicio de la región. Tales cosas incluyen trabajar con cadenas terminadas en nulo, manipular los primeros n bytes de la región (si se sabe que la región es al menos así de grande), y así sucesivamente.

Básicamente, hacer un seguimiento de la longitud de una región es trabajo adicional, y si C lo hiciera automáticamente, a veces lo haría innecesariamente.

Muchas funciones de la biblioteca (por ejemplo, fread() ) requieren un puntero al comienzo de una región, y también el tamaño de esta región. Si necesita el tamaño de una región, debe hacer un seguimiento de ello.

Sí, las implementaciones de malloc () generalmente hacen un seguimiento del tamaño de una región, pero pueden hacerlo indirectamente o redondearlo a algún valor o no mantenerlo en absoluto. Incluso si lo admiten, encontrar el tamaño de esta manera puede ser lento en comparación con el seguimiento de usted mismo.

Si necesita una estructura de datos que sepa cuán grande es cada región, C puede hacer eso por usted. Simplemente use una estructura que haga un seguimiento de qué tan grande es la región, así como un puntero a la región.


No estoy seguro, pero intenta:

char **q = &p; int size = q[1] - q[0];


No hay una forma estándar de encontrar esta información. Sin embargo, algunas implementaciones proporcionan funciones como msize para hacer esto. Por ejemplo:

Sin embargo, tenga en cuenta que malloc asignará un mínimo del tamaño solicitado, por lo que debe comprobar si la variante msize para su implementación realmente devuelve el tamaño del objeto o la memoria realmente asignada en el montón.


No, la biblioteca C runtime no proporciona esa función.

Algunas bibliotecas pueden proporcionar funciones específicas de plataforma o compilador que pueden obtener esta información, pero en general la forma de hacer un seguimiento de esta información se encuentra en otra variable entera.


No, no hay.


Si usa malloc, entonces no puede obtener el tamaño.

Por otro lado, si utiliza la API del sistema operativo para asignar dinámicamente la memoria, como las funciones del montón de Windows, entonces es posible hacer eso.


Todo el mundo diciéndole que es imposible es técnicamente correcto (el mejor tipo de corrección).

Por razones de ingeniería, es una mala idea confiar en el subsistema malloc para decirle con precisión el tamaño de un bloque asignado. Para convencerte de esto, imagina que estás escribiendo una aplicación grande , con varios asignadores de memoria diferentes; tal vez uses raw libc malloc en una parte, pero operator new C ++ operator new en otra parte, y luego alguna API específica de Windows en otra parte. Así que tienes todo tipo de void* volando. Escribir una función que pueda funcionar en cualquiera de estos void* es imposible, a menos que de algún modo pueda determinar a partir del valor del puntero de cuál de sus montones proviene.

Así que es posible que desee envolver cada puntero en su programa con alguna convención que indique de dónde proviene el puntero (y dónde debe devolverse). Por ejemplo, en C ++ llamamos a std::unique_ptr<void> (para punteros que necesitan ser operator delete ''d) o std::unique_ptr<void, D> (para punteros que deben devolverse a través de algún otro mecanismo D ) Podrías hacer el mismo tipo de cosas en C si quisieras. Y una vez que termine con los punteros en objetos más grandes y seguros, es solo un pequeño paso para struct SizedPtr { void *ptr; size_t size; } struct SizedPtr { void *ptr; size_t size; } struct SizedPtr { void *ptr; size_t size; } y luego nunca más tendrá que preocuparse por el tamaño de una asignación.

Sin embargo.

También hay buenas razones por las que legítimamente podría querer saber el tamaño subyacente real de una asignación. Por ejemplo, tal vez esté escribiendo una herramienta de creación de perfiles para su aplicación que informará la cantidad real de memoria utilizada por cada subsistema, no solo la cantidad de memoria que el programador pensó que estaba utilizando. Si cada una de sus asignaciones de 10 bytes está secretamente usando 16 bytes debajo del capó, ¡es bueno saberlo! (Por supuesto que habrá otros gastos generales también, que no está midiendo de esta manera. Pero hay otras herramientas para ese trabajo). O tal vez solo está investigando el comportamiento de realloc en su plataforma. O tal vez le gustaría "redondear" la capacidad de una asignación creciente para evitar reasignaciones prematuras en el futuro. Ejemplo:

SizedPtr round_up(void *p) { size_t sz = portable_ish_malloced_size(p); void *q = realloc(p, sz); // for sanitizer-cleanliness assert(q != NULL && portable_ish_malloced_size(q) == sz); return (SizedPtr){q, sz}; } bool reserve(VectorOfChar *v, size_t newcap) { if (v->sizedptr.size >= newcap) return true; char *newdata = realloc(v->sizedptr.ptr, newcap); if (newdata == NULL) return false; v->sizedptr = round_up(newdata); return true; }

Para obtener el tamaño de la asignación detrás de un puntero no nulo que ha sido devuelto directamente desde libc malloc , no desde un montón personalizado, y no apuntando hacia el centro de un objeto, puede usar las siguientes API específicas del sistema operativo, que se han agrupado en una función de envoltura "portable-ish" para mayor comodidad. Si encuentra un sistema común donde este código no funciona, ¡deje un comentario y trataré de solucionarlo!

#if defined(__linux__) // https://linux.die.net/man/3/malloc_usable_size #include <malloc.h> size_t portable_ish_malloced_size(const void *p) { return malloc_usable_size((void*)p); } #elif defined(__APPLE__) // https://www.unix.com/man-page/osx/3/malloc_size/ #include <malloc/malloc.h> size_t portable_ish_malloced_size(const void *p) { return malloc_size(p); } #elif defined(_WIN32) // https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/msize #include <malloc.h> size_t portable_ish_malloced_size(const void *p) { return _msize((void *)p); } #else #error "oops, I don''t know this system" #endif #include <stdio.h> #include <stdlib.h> // for malloc itself int main() { void *p = malloc(42); size_t true_length = portable_ish_malloced_size(p); printf("%zu/n", true_length); }

Probado en:


comp.lang.c Lista de preguntas frecuentes · Pregunta 7.27 -

P. Entonces, ¿puedo consultar el paquete malloc para averiguar qué tan grande es un bloque asignado?

R. Desafortunadamente, no hay una forma estándar o portátil. (Algunos compiladores proporcionan extensiones no estándar). Si necesita saberlo, tendrá que hacer un seguimiento de ello usted mismo. (Véase también la pregunta 7.28 .)


int *a; a=malloc(n*sizeof(int)); si malloc devuelve NULL, significa que no obtuvo la memoria; de lo contrario, obtendrá la dirección base del bloque asignado, es decir, el tamaño de bloque (n*sizeof(int)) .