Concatenar cadenas con memoria dinámica en lenguaje C.

Iniciado por NOB2014, 19 Junio 2016, 14:33 PM

0 Miembros y 1 Visitante están viendo este tema.

NOB2014

Hola, gente.
Les quito un poco de tiempo porque si bien estoy leyendo que es lo que causa el doble free no logro solucionarlo por mí mismo y si lo lograra me quedarían dudas en la función concatenar, les digo esto porque si bien logre que no me diera error en la compilación lo hice a fuerza de prueba/error/solución pero no teniendo claro que es lo que estaba haciendo. -
Las cosas que no me quedan claras:

1): Porque debo hacer que la función se declare como un puntero a función.
2): Porque el error del doble free.
3): Como se hace para poner un espacio entre las dos frases (por programación, claro).-
 
#include <stdio.h>
#include<string.h>
#include<stdlib.h>

#define MAX 51

void ingreso( char origUno[], char origDos[] );
void limpiarBuffer( char cadena[] );
char *concatenar( char *origUno, char *origDos );

int main( void ){
char origUno[MAX] = "", origDos[MAX] = "", *ptrConc = NULL;

ingreso( origUno, origDos );
ptrConc = concatenar( origUno, origDos );

printf("\n %s", ptrConc);

free(ptrConc);

return 0;
}

void ingreso( char origUno[], char origDos[] ){

printf( "\n Ingrese una frase(maximo %d caracteres)............:", MAX-1 );
fgets(origUno, MAX, stdin);
limpiarBuffer( origUno );

printf( "\n Ingrese frase a concatenar (maximo %d caracteres)..:", MAX-1 );
fgets(origDos, MAX, stdin);
limpiarBuffer( origDos );
}

void limpiarBuffer( char cadena[] ){
char *p = NULL;
size_t ch;

if((p=strchr(cadena, '\n'))){
*p='\0';
}
else{
while((ch = getchar()) !='\n' && ch!=EOF);
}
}

char *concatenar( char *origUno, char *origDos ){
size_t totCarac = strlen( origUno ) + strlen( origDos ) + 1;
char *arr = ( char* )malloc( totCarac * sizeof(char) );
arr = strcat( origUno, origDos );

return arr;
}


Saludos y desde ya muchas gracias. -
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

AlbertoBSD

#1
Cita de: NOB2014 en 19 Junio 2016, 14:33 PM

1): Porque debo hacer que la función se declare como un puntero a función.


Es el tipo de dato que devuelve la funcion, no es que sea un puntero a funcion, es una funcion que devuelve un tipo de  dato
;
char* funcion();

No veo ningun doble free en tu codigo. Lo que veo es que estas tratando de liberar una sección de memoria no liberable. Esto es que solo puedes liberar memoria reservada por malloc, calloc y realloc pero tu apuntador posteiormente apunta a origUno por el strcat que haces incorrectamente.

Segun:

char *arr = ( char* )malloc( totCarac * sizeof(char) );

Reservas memoria el buffer completo pero despues reasignas el valor de arr a la direccio  de origUno.

arr = strcat( origUno, origDos );

que seria la direccion de origUno...

Necesitas primero realizar un strncpy de origUno a arr y luego realizar la concatenacion.

Sobre el espacio tendrias que hacer:

strcpy(arr,origUno);
strcat( arr, " ");
strcat( arr, origDos );



Nota que uso strcpy y no strncpy ya que como capturaste correctamente origUno y reservastes memoria suficiente para arr no hay riesgo de bufferoverflow. En cualquier otro caso usaria strncpy...

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

NOB2014

Hola, Alberto. -
Muchas gracias amigo funciona a la perfección, pero igual me queda una duda y es que al tener un espacio creado con:
strcat( arr, " ");
¿no debería reservar un espacio más?  
size_t totCarac = strlen( origUno ) + strlen( origDos ) + 1;
Un abrazo.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

AlbertoBSD

Así es se me paso comentar eso.

Debería de ser +2 en lugar de +1.

Saludos.
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW