2010-02-14 20 views
11

Duplicar posible:
newbie questions about malloc and sizeofsizeof() en la memoria malloc'd

Estoy intentando leer las cadenas en un programa. Cuando me di cuenta de que a veces las cuerdas estaban siendo corrompidos, probé el siguiente código:

void *mallocated = malloc(100); 
printf("sizeof(mallocated) = %d\n", sizeof(mallocated)); 

De acuerdo con mi programa, el tamaño de mallocated era 8, a pesar de que asignaron 100 bytes por ello. Debido a esto, cada vez que trato de almacenar una cadena de más de 8 bytes, todo lo que se encuentra después del octavo byte a veces desaparecerá. ¿Por qué está sucediendo esto y cómo puedo prevenirlo?

+4

sizeof (mal localizado) le dará el tamaño de vacío * que es de 8 bytes en su sistema de 64 bits. ¿Cómo se asigna una cadena a esa variable, con strcpy? – tur1ng

+0

Ver: http://stackoverflow.com/questions/1533519/newbie-questions-about-malloc-and-sizeof – Shog9

+0

Su conclusión es incorrecta también, cualquier cosa escrita después del octavo "byte" (no poco) no desaparece al azar a veces. – Blindy

Respuesta

13

Porque el tamaño del puntero de "cadena" es de 8 bytes. Estos son algunos ejemplos del uso de sizeof() con su "tamaño" apropiado. El término size_of() a veces engaña a las personas que no están acostumbradas a usarlo. En su caso, el tamaño del puntero es de 8 bytes. A continuación se muestra una representación en un sistema típico de 32 bits.

sizeof (char) = 1 
sizeof (double) = 8 
sizeof (float) = 4 
sizeof (int) = 4 
sizeof (long) = 4 
sizeof (long long) = 8 
sizeof (short) = 2 
sizeof (void *) = 4 

sizeof (clock_t) = 4 
sizeof (pid_t) = 4 
sizeof (size_t) = 4 
sizeof (ssize_t) = 4 
sizeof (time_t) = 4 

Source

Usted está saliendo de cómo se está determinando su secuencia está desapareciendo (matriz de caracteres). Probablemente se pase a una función, que necesita pasar la longitud explícita como variable o rastrearla en algún lugar. Usar sizeof() no te dirá esto.

Consulte mi previous question acerca de esto y verá incluso mi falta de comprensión inicial.

+0

Gracias por la ayuda. El problema con el programa no fue exactamente lo que pensé que era (¿alguna vez?) Pero tu consejo fue muy útil. –

7

En C89, sizeof operador sólo encuentra el tamaño de una variable en bytes en tiempo de compilación (en este caso un puntero void de 8 bytes). Funciona de la manera que esperaría que funcionara en arreglos simples, porque su tamaño es conocido en tiempo de compilación.

char arr[100]; // sizeof arr == 100 
char *p = arr; // sizeof p == 4 (or 8 on 64-bit architectures) 
char *p = malloc(100); // sizeof p == 4 (or 8). Still! 

saber el tamaño de la pila de memoria asignada, es necesario hacer un seguimiento de forma manual, sizeof no le ayudará.

+1

Eso no es verdad. En C99, 'sizeof' devuelve el tamaño de una matriz de longitud variable, que en muchos casos solo se puede determinar en tiempo de ejecución. – dreamlax

+0

Gracias, excluí el caso C99 de la respuesta para simplificar las cosas. –

7

sizeof devuelve el tamaño del puntero (void *) que le proporcionó, no el tamaño de la memoria que asignó. Debería almacenar el tamaño de la memoria en una variable separada si desea usarla más adelante.

3

No puede. Como se señaló, puede obtener el tamaño del void * mal localizado, pero eso no le dice mucho.

Usted no puede obtener el tamaño de la malloed *mallocated. Es decir, no hay una llamada de función para devolver 100 (en su ejemplo), a menos que escriba sus propias rutinas de administración de memoria.

más simple es sólo para recordar que en alguna parte ... tal vez ....

stuct { 
    void *data; 
    unsigned int size 
} myStructureWhichRemebersItsSize; 

myStructureWhichRemebersItsSize *someData; 
someData.data = malloc(100); // and check for NULL 
someData.size = 100; 
+1

"No se puede obtener el tamaño de Malloed" ... No es cierto, depende de sus bibliotecas de C. En CRT STDLIB de MS, puede simplemente llamar a '_msize (* mallocated)' para obtener el "100" que busca el OP. –

+0

+1 Gracias por la información. No uso MS, así que no lo sabía. Una característica útil que sería agradable de ver en más lugares. Por supuesto, detrás de escena, el compilador probablemente esté generando una estructura como la que describo. – Mawg

0

void* es el tipo de un lugar en la memoria si usted no sabe lo que contiene. Debe ser evitado

char* es el tipo de valor que apunta a una ubicación en la memoria que contiene un char. La identificación de una ubicación en la memoria requiere ocho bytes.

sizeof le dice cuántos bytes ocupa un tipo particular. No cuántos se asignaron con malloc, pero la cantidad de memoria que conoce el compilador del tipo debe tomar. Aplicar sizeof a los valores a menudo se considera de mal estilo, y como alguien más mencionado aquí, a veces invoca un comportamiento inteligente en C99.

char[100] tipo de valor que contiene 100 caracteres. char[100] a; es una cadena de 100 char s en la pila.

es el tipo de un puntero a un valor que contiene 100 caracteres. char(*b)[100]; hace b apunta a 100 caracteres, posiblemente en el montón. Lo que probablemente quiera es

char (*s)[100] = malloc(sizeof(char[100])); 
printf("%u byte pointer to %u bytes of size %u elements\n", 
    sizeof s, sizeof *s, sizeof **s);