2010-04-28 13 views
8

gcc 4.4.1 c89sizeof con una matriz asignada dinámicamente

tengo el siguiente fragmento de código:

#include <stdlib.h> 
#include <stdio.h> 

char *buffer = malloc(10240); 
/* Check for memory error */ 
if(!buffer) 
{ 
    fprintf(stderr, "Memory error\n"); 
    return 1; 
} 
printf("sizeof(buffer) [ %d ]\n", sizeof(buffer)); 

Sin embargo, el sizeof (tampón) siempre imprime 4. Sé que un char * es solo 4 bytes. Sin embargo, he asignado la memoria para 10kb. Entonces, ¿no debería el tamaño ser 10240? Me pregunto, ¿estoy pensando aquí?

Muchas gracias por todas las sugerencias,

+2

En su mayor parte, el compilador de C (para cualquier versión) no tiene idea de qué función o para qué se utiliza la función 'malloc'. Todo lo que sabe es que toma un entero sin signo (size_t) y devuelve un puntero de vacío. Podría usar su parámetro para inicializar el generador de números aleatorios y convertir un número aleatorio en un '(void *)' para todos los problemas del compilador, por lo que el compilador no puede saber a qué apunta el tamaño de la memoria. – nategoose

Respuesta

14

Usted está pidiendo el tamaño de un char* que es 4 de hecho, no el tamaño del búfer. El operador sizeof no puede devolver el tamaño de un búfer asignado dinámicamente, solo el tamaño de los tipos y estructuras estáticos conocidos en tiempo de compilación.

+2

'sizeof' puede devolver el tamaño de un búfer dinámico para matrices de longitud variable en C99. –

+0

¿Hay algún método en c89 que pueda encontrar la cantidad de memoria asignada con un búfer asignado dinámicamente? Gracias. – ant2009

+2

@Carl - Los VLA no son dinámicos. Son de "longitud variable", ya que su longitud se puede calcular en tiempo de ejecución, pero no como "longitud variable", ya que su longitud puede cambiar. Todavía son matrices basadas en la pila, por lo que 'sizeof' se define para que funcione para ellos. –

9

sizeof no funciona en las asignaciones dinámicas (con algunas excepciones en C99). Su uso de sizeof aquí le está dando el tamaño del puntero. Este código le dará el resultado deseado:

char buffer[10240]; 
printf("sizeof(buffer) [ %d ]\n", sizeof(buffer)); 

Si malloc() tiene éxito, la memoria apuntada es al menos tan grande como usted pidió, así que no hay razón para preocuparse por el tamaño real asignó.

Además, ha asignado 10 kB, no 1 kB.

+0

Este código es más que un poco peligroso: está asignando el búfer en la pila, no en el montón. Si deja que los punteros a este búfer se filtren fuera de la función que lo declara, estará en el camino de acumular daños (y dependiendo de cuánto tiempo se ejecute su programa, corrupción de montones y/o un error de segmentación). – Anon

+2

@Anon - No es peligroso, simplemente resuelve el problema de otra manera. El OP no tenía requisitos para pasar el búfer de una función. –

+0

¿Y cuál es exactamente el problema del OP?Me parece que está haciendo un seguimiento del tamaño de una estructura asignada en el montón. Sugerir que el OP use una estructura asignada por la pila no es una solución a ese problema. – Anon

3

Depende de usted realizar un seguimiento del tamaño de la memoria si la necesita. La memoria devuelta por malloc es solo un puntero a los datos "no inicializados". El operador sizeof solo está trabajando en la variable buffer.

+0

Seguramente el entorno de tiempo de ejecución sabe el tamaño del búfer asignado (porque 'free (void *)' no solicita el tamaño), entonces ¿por qué deberíamos hacer un seguimiento de nosotros mismos? – Dai

+0

El código de administración de memoria subyacente casi seguramente tiene el tamaño a menos que tenga algún algoritmo mágico para liberar que no requiera tamaño. Pero esa información no está expuesta. –

+0

¿Hay algún motivo por el que los datos no estén expuestos? – Dai

2

Reemplace su sizeof por malloc_usable_size (la página de manual indica que esto no es portátil, por lo que puede no estar disponible con su implementación C en particular).

+1

'malloc_usable_size()' es muy no portátil. No lo tengo en OS X Leopard. De todos modos, confiar en él es una idea terrible en primer lugar (como también se indica en la página de manual). –

+0

NOTA: si no te importa la portabilidad y estás en OSX (o si a alguien más no le importa y estás atascado con la migración a OSX) malloc_size de es tu hombre para el trabajo. – Stripes

3

No. buffer es un char *. Es un puntero a char de datos. El puntero solo ocupa 4 bytes (en su sistema).

Señala 10240 bytes de datos (que, por cierto, no es 1Kb. Más como 10Kb), pero el puntero no sabe que. Considere:

int a1[3] = {0, 1, 2}; 
int a2[5] = {0, 1, 2, 3, 4}; 

int *p = a1; 
// sizeof a1 == 12 (3 * sizeof(int)) 
// but sizeof p == 4 
p = a2 
// sizeof a2 == 20 
// sizeof p still == 4 

Es la principal diferencia entre matrices y punteros. Si no funciona de esa manera, sizeof p cambiaría en el código anterior, lo que no tiene sentido para una constante de tiempo de compilación.

Cuestiones relacionadas