2011-05-23 14 views
5
#inlcude <stdio.h> 
#inlcude <stdlib.h> 
#inlcude <string.h> 

int main() { 
    char *buff = (char*)malloc(sizeof(char) * 5); 
    char *str = "abcdefghijklmnopqrstuvwxyz"; 

    memcpy (buff, name, strlen(str)); 

    while(*buff) { 
     printf("%c" , *buff++); 
    } 

    printf("\n"); 

    return 0; 
} 

este código imprime toda la cadena "abc ... xyz". pero "buff" no tiene memoria suficiente para mantener esa cadena. ¿Cómo funciona memcpy()? usa realloc()?¿Memcpy() usa realloc()?

Respuesta

10

Su código tiene Comportamiento indefinido. Para responder a su pregunta, NO, memcpy no utiliza realloc. sizeof(buf) debe ser adecuado para acomodar strlen(str). Cualquier cosa menos es un choque.

La salida puede imprimirse ya que es un programa pequeño, pero en código muy grande causará errores difíciles de depurar. Cambiar el código para,

const char* const str = "abcdefghijklmnopqrstuvwxyz"; 
char* const buff = (char*)malloc(strlen(str) + 1); 

Además, no hacer *buff++ debido a que va a perder el registro de memoria (lo que asignados). Después de malloc() uno debe hacer free(buff) una vez que el uso de la memoria ha terminado, de lo contrario es una pérdida de memoria.

+3

+1 para la respuesta a la pregunta directa. –

+0

quiero usar este buffer para mantener una cadena en mi aplicación real. esa cadena no tiene una longitud predefinida. crece dinámicamente (añadiendo algunas otras cadenas ...) cuando el programa se está ejecutando. la solución que encontré es asignar algo de gran memoria (~ 1KB). Quiero saber si hay otras soluciones diferentes a esta ?. por favor ayuda. Gracias. – shan

+0

@shan, entonces puede usar 'realloc()' (pero no 'memcpy()') para ese propósito. – iammilind

8

Es posible que esté imprimiendo toda la cadena, pero no es seguro y está escribiendo y leyendo desde la memoria no asignada. Esto produce un comportamiento indefinido.

memcpy no hace ninguna asignación de memoria. Simplemente lee y escribe en las ubicaciones que proporcione. No verifica si está bien hacerlo, y en este caso tiene suerte si su programa no falla.

+0

Gracias por la respuesta. pero, si no conozco la longitud de la cadena, ¿cómo puedo asignar suficiente memoria? quiero hacer un buffer Quiero evitar escribir y leer desde la memoria no asignada. ¿Cuáles son los cambios que tengo que hacer en mi código? por favor ayuda ? gracias – shan

+0

@shan - Si está llamando 'memcpy', y sabe cuánta memoria va a copiar, entonces sabrá cuánta memoria necesita asignar. Use 'strlen' para encontrar la longitud de una cadena (busca el carácter nulo de terminación). – sje397

+0

Sí, usa 'strlen', tal como lo hizo para su' memcpy', excepto por un detalle. La función 'strlen' no cuenta el carácter nulo de terminación. Por lo tanto, tanto en 'malloc' como en' memcpy' necesita usar 'strlen (str) + 1'. Además, no es necesario multiplicar por 'sizeof (char)' en el malloc. por definición 'sizeof (char) == 1'. – andrewdski

1

cómo funciona memcpy()?

Porque has invocado un comportamiento indefinido. El comportamiento indefinido puede funcionar exactamente como usted espera, y puede hacer algo completamente diferente. Incluso puede diferir entre diferentes ejecuciones del mismo programa. También podría formatear el disco duro y seguir cumpliendo con el estándar (aunque, por supuesto, es poco probable: P)

Comportamiento no definido significa que el comportamiento no está literalmente definido para hacer nada. Todo es válido, incluido el comportamiento que estás viendo. Tenga en cuenta que si intenta free esa memoria, el tiempo de ejecución de C de su plataforma de destino probablemente se queje. ;)

1

No memcpy no utiliza malloc. Como sospechaba, está escribiendo al final de buff. En su ejemplo simple, eso no causa ningún daño aparente, pero es malo. Estas son algunas de las cosas que podrían salir mal en un programa de "real":

  • Es posible hacer garabatos en algo asignado en la memoria después de su buff dando lugar a sutiles (o no tan sutiles) errores más adelante.
  • Puede garabatear en los encabezados utilizados internamente por malloc y free, lo que puede causar bloqueos u otros problemas en su próxima llamada a esas funciones.
  • Puede terminar escribiendo en una dirección que no ha sido asignada a su proceso, en cuyo caso su programa se bloqueará inmediatamente. (Sospecho que esto es lo que estabas esperando.)

Hay malloc implementaciones que ponen páginas de protección sin asignar alrededor asignados a la memoria (por lo general) que el programa se bloquee en casos como este.Otras implementaciones detectarán esto, pero solo en su próxima llamada al malloc o free (o cuando llame a una función especial para verificar el montón).