2011-04-10 13 views
6

Tengo dos cadenas, str1 y str2. Quiero la concatenación de ellos en un espacio en el montón. Me MALLOC espacio para ellos usando:¿Manera correcta de malloc espacio para una cadena y luego insertar caracteres en ese espacio?

char *concat = (char*) malloc(strlen(str1) + strlen(str2) + 1); 

¿Puedo hacer:

strcat(concat, str1); 
strcat(concat, str2); 

Y concat me dará el lugar en el montón con las dos cadenas concatted? Lo estoy preguntando porque parece que strcat realmente agregaría str1 al final del espacio asignado usando malloc. ¿Es esto correcto? Entonces, str1 aparecería en la posición strlen (str1) + strlen (str2) + 1.

La razón por la que estoy preguntando es que estoy usando el método anterior, pero estoy obteniendo un error en valgrind: salto condicional o movimiento depende de valor sin inicializar (s)

Respuesta

11

Lo strcat(dest, src) que realmente hace es buscar el un byte nulo a partir de las dest y en el futuro, y luego escribir la cadena src allí.

Después de malloc, los contenidos de la memoria no están definidos, por lo que su código actual podría hacer cualquier cantidad de cosas, la mayoría de ellas incorrectas. Si hace concat[0] = 0 antes de strcat, entonces su código funciona pero tendrá que buscar la longitud de str1 tres veces - una vez para strlen, otra vez para la primera strcat, y la última para la segunda strcat.

En cambio, sin embargo, recomiendo el uso de memcpy:

size_t len1 = strlen(str1), len2 = strlen(str2); 
char *concat = (char*) malloc(len1 + len2 + 1); 

memcpy(concat, str1, len1); 
memcpy(concat+len1, str2, len2+1); 

Esto se aprovecha del hecho de que usted sabe desde el principio en el que desea que los bytes de ambas cadenas para el final, y cuántos son.

+0

+1 Definitivamente una muy buena manera de hacerlo. Probablemente usaría 'memmove()' en lugar de 'memcpy()' porque, aunque 'memcpy()' es seguro en esta situación, no siempre es seguro, pero 'memmove()' siempre es seguro. –

+4

No use 'memmove' aquí; es confuso. Cualquier uso de 'memmove' debería servir para documentar que estás haciendo algo muy diferente e inusual. Si viera 'memmove' aquí me gustaría pasar uno o dos minutos tratando de descubrir por qué el # * $ @ alguien lo usó y si algo sospechoso estaba sucediendo ... –

4

¿quieres hacer un strcpy y luego un strcat:

strcpy(concat, str1); 
strcat(concat, str2); 

strcat se basa en la existencia de un terminador nulo ('\ 0') para saber dónde empezar. Si simplemente malloc y strcat, va a hacer algunas cosas desagradables.

Y no, ni strcpy ni strcat harán ningún tipo de asignación o reasignación implícita.

4

lo haría personalmente lo siguiente:

size_t length = strlen(str1) + strlen(str2) + 1; 
char *concat = malloc(sizeof(char) * length); 

if(concat == NULL) 
{ 
    // error 
} 

snprintf(concat, length, "%s%s", str1, str2); 
+0

+1 por mencionar la verificación de error. 'snprintf()' a menudo es una buena solución, aunque limita con el exceso aquí. –

+2

No use 'strlen' para calcular la longitud. Use 'length = snprintf (0,0,"% s% s ", str1, str2);' O simplemente use 'asprintf' (y asegúrese de incluir su propia versión, es un contenedor trivial alrededor de' snprintf' - para sistemas que no incluyen esta extensión de GNU). –

+2

Justificación del comentario de R anterior aquí mismo (debe leer para entender el consejo): http://stackoverflow.com/a/5615561/340236 – San

Cuestiones relacionadas