gcc 4.4.1 c89

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, la sizeof(buffer) imprime siempre 4. Yo sé que un char* sólo es de 4 bytes. Sin embargo, me han asignado la memoria de 10kb. Así que no debería el tamaño de 10240? Me pregunto estoy pensando aquí?

Muchas gracias por cualquier sugerencia,

Para la mayor parte del compilador de C (para cualquier versión) no tiene ninguna idea de lo que la función de malloc realmente hace o se utiliza para. Todo lo que sabe es que toma un entero sin signo (size_t) y devuelve un puntero nulo. Se podría utilizar el parámetro de la semilla del generador de números aleatorios y echó un número aleatorio a un (void *) para todos el compilador le importa, por lo que el compilador no puede saber lo que el tamaño de la memoria que apunta es.

OriginalEl autor ant2009 | 2010-04-28

5 Comentarios

  1. 15

    Usted está pidiendo el tamaño de un char* que es 4 de hecho, no es el tamaño de la memoria intermedia. El sizeof operador no puede devolver el tamaño de búfer asignado dinámicamente, sólo el tamaño de la estática de tipos y estructuras conocido en tiempo de compilación.

    sizeof puede devolver el tamaño de una dinámica de búfer para la variable longitud de las matrices en C99.
    ¿Hay algún método en c89 que usted puede encontrar la cantidad de memoria que ha sido asignado con un búfer asignado dinámicamente? Gracias.
    VLA no son dinámicos. Ellos son “de longitud variable” en que su longitud puede ser calculada en tiempo de ejecución, pero no “de longitud variable” en que su longitud puede cambiar. Todavía están basado en pila de matrices, que es la razón por la sizeof se define a trabajar para ellos.
    Seguir la pista de sí mismo utilizando un struct { char *buf; size_t len; };. O el uso de otra persona de la cadena de la biblioteca. O mantener una estricta adhesión a los “pase siempre longitudes con buffers” de la regla (que probablemente debería hacer de todos modos).
    no hay manera de saber cuánta memoria malloc() en realidad le dio sin otros OS/características de la biblioteca que podría ser capaz de decirle. Esos serán de sistema operativo/depende del compilador.

    OriginalEl autor

  2. 9

    sizeof no funciona en asignaciones dinámicas (con algunas excepciones en C99). El uso de sizeof aquí es simplemente dándole el tamaño del puntero. Este código te dará el resultado que usted desea:

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

    Si malloc() se realiza correctamente, la memoria que apunta es al menos tan grande como usted lo pidió, así que no hay razón de preocuparse por la real tamaño asignados.

    También, se han asignado 10 kB, no 1 kB.

    Este código es más que un poco peligroso: es la asignación del buffer en la pila, no el montón. Si dejas que los punteros a este búfer se salga de la función que se declara, usted está en el camino a la pila de la corrupción (y dependiendo del tiempo que su programa se ejecuta, el montón de corrupción y/o un fallo de segmentación).
    No es peligroso, sólo resuelve el problema de una manera diferente. El OP no tenía los requisitos acerca de pasar el búfer de regreso de una función.
    Y qué, exactamente, es el OP del problema? A mí me parece que es mantener el control del tamaño de un montón asignado en la estructura. Lo que sugiere que el OP utiliza una pila asignado en la estructura no es una solución a ese problema.

    OriginalEl autor

  3. 3

    Es hasta usted para realizar el seguimiento del tamaño de la memoria si la necesita. La memoria devuelto por malloc es sólo un puntero a “no inicializado” de datos. El operador sizeof sólo está trabajando en la buffer variable.

    Sin duda el entorno de tiempo de ejecución se conoce el tamaño del búfer asignado (porque free(void*) no pregunte por el tamaño), así que ¿por qué tenemos que seguir la pista de nosotros mismos?
    La memoria subyacente de gestión de código casi seguro que tiene el tamaño a menos que haya algún mágico algoritmo para liberar a los que no requiere de tamaño. Pero esa información no está expuesto.
    Hay una razón por la que los datos no expuestos?
    No fue definido de esa manera. Esta respuesta, explica.

    OriginalEl autor

  4. 3

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

    Apunta a 10240 bytes de datos (que, por cierto, no es un tamaño de 1 kb. Más como 10Kb), pero el puntero no sabe que. Considerar:

    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 arrays y punteros. Si no funciona de esa manera, sizeof p iba a cambiar en el código de arriba, que no tiene sentido para una constante en tiempo de compilación.

    OriginalEl autor

  5. 2

    Reemplazar su sizeof por malloc_usable_size (el manual indica que este no es portable, por lo que no estarán disponibles para su implementación en C).

    malloc_usable_size() no es muy portátil. Yo no lo tengo en OS X Leopard. De todos modos, la confianza en que es una idea terrible, en primer lugar (como también se indica en el manual).
    NOTA: si usted no se preocupan acerca de la portabilidad y en OSX (o alguien más no le importaba y le pegan con la migración a OSX) malloc_size de <malloc/malloc.h> es el hombre para el trabajo.

    OriginalEl autor

Dejar respuesta

Please enter your comment!
Please enter your name here