2010-06-04 17 views
7

¿Es la forma correcta de asignar memoria a un char *?Asignación de memoria a char * Lenguaje C

char* sides ="5"; 

char* tempSides; 

tempSides = (char*)malloc(strlen(inSides) * sizeof(char)); 
+0

@brickner lo que sobre esto en strlen, strlen (interior) + 1 – boom

Respuesta

14

Casi. Las cadenas tienen terminación NULL, por lo que probablemente desee asignar un byte extra para almacenar el byte NULL. Es decir, aunque sides tiene 1 carácter, en realidad es 2 bytes: {5, '\0'}.

por lo que sería:

tempSides = (char *)malloc((strlen(sides)+1)*sizeof(char)); 

y si quieres copiarlo en:

strcpy(tempSides, sides); 
+8

¿Quiere decir '\ 0' cuando dice NULL. '\ 0' es nul, no NULL. –

+0

Tenga en cuenta que multiplicar por 'sizeof (char)' no es necesario; 'sizeof (char)' se define como 1. – caf

+2

@caf: Es cierto, pero omitirlo hace que sea más difícil adaptar el código a wchar_t o TCHAR cuando sea necesario; si no hay multiplicaciones existe el riesgo de olvidarse de usar una. – sharptooth

1

hay un problema con eso. tempSides apuntará a un bloque de memoria no inicializado de tamaño 1. Si tiene la intención de copiar la cadena de lados en tempSides, necesitará asignar un tamaño de un byte más para mantener el cero terminador de la cadena. El valor devuelto por strlen() no incluye el terminador cero al final de la cadena.

1

No, realmente no. Como ya han notado otros, necesita asignar espacio para el terminador NUL.

Además, generalmente debe no emitir el retorno desde malloc. Puede cubrir un error donde ha olvidado #include el encabezado correcto. Multiplicando por sizeof(char) también es inútil, ya que las normas (tanto en C y C++) definen sizeof(char) ser siempre 1.

Por último, cada llamada a malloc debe incluir una prueba del resultado. Me envuelvo todo el asunto en una función:

char *dupe_string(char const *string) { 
    char *temp; 
    if (NULL!=(temp=malloc(strlen(string)+1))) 
     strcpy(temp, string); 
    return temp; 
} 
3

Como se ha señalado, se perdió la asignación de espacio para la terminación de chararacter NUL. Pero también quería señalar un par de otras cosas que pueden hacer que su código sea más conciso.

Por definición, sizeof(char) es siempre 1, por lo que puede acortar su línea de asignación a:

tempSides = (char*)malloc(strlen(inSides) + 1); 

Otra cosa es que esto parece que está haciendo para duplicar la cadena. Hay una construida en función de que lo hace por usted:

tempSides = strdup(inSides); 

Este se encarga de conseguir la longitud, asignando el número correcto de bytes y la copia de los datos.

9

Tenga en cuenta que:

  1. Las cadenas son terminados en cero (\ 0), y strlen() no contarlo;
  2. Por definición, sizeof (char) es 1 (byte), por lo que no es obligatorio;
  3. Si utiliza un compilador C (no C++), no hay necesidad de convertirlo a char *;

por lo que sería:

char *tempSides = malloc(strlen(inSides) + 1); 

embargo, si usted quiere duplicar el contenido de inSides, puede utilizar strdup, por ejemplo:

char *tempSides = strdup(inSides); 
if (tempSides != NULL) { 
    // do whatever you want... 
    free(tempSides); 
} 
0

Multiplicando el contador de elementos por sizeof(char) es una cuestión de preferencia personal, ya que sizeof(char) siempre es 1. Sin embargo, si hace esto por consistencia, use mejor t El tipo de puntero del destinatario para determinar el tamaño del elemento, en lugar de especificarlo explícitamente. Y no emitir el resultado del malloc

tempSides = malloc(strlen(inSides) * sizeof *tempSides); 

Por supuesto, cuando se trabaja con cadenas terminadas en cero usted tiene que recordar para asignar espacio adicional para el carácter cero de terminación. No hay manera de decir si su intención es hacer que tempSides sea una cadena con terminación cero en este caso, por lo que no puedo decir si la necesita.

+0

¿De ninguna manera? Será mejor que use cadenas terminadas en cero cuando llame a 'strlen' ... Si usa su propio strlen, entonces realmente no quiero ser el programador de mantenimiento después de él. ;) – Secure

+1

@Secure: Eso solo significa que 'inSides' tiene terminación cero. No hay indicación en el código de que 'tempSides' deba terminarse en cero también. – AnT

0

La forma correcta de memoria dinámica asignación a tempSides es como se muestra a continuación:

char* sides ="5"; 
char* tempSides; 
tempSides = (char*)malloc((strlen(sides) + 1) * sizeof(char)); 

char* tiendas unos datos de cadena, similar a char[]. Las cadenas son null (\0) terminadas. Por lo tanto, se debe asignar un byte adicional para el almacenamiento de caracteres null.

El bloque de memoria asignado dinámicamente debe liberarse usando free() después de que se haya terminado su uso. Si no se libera, se produciría una pérdida de memoria.

free(tempSides); 

Uno se libera la memoria, NULL debe asignarse a evitar que sea una referencia colgante.

tempSides = NULL;