Discussion:
Segmentation default al retornar.
(demasiado antiguo para responder)
AntyDesk
2004-01-22 10:52:59 UTC
Permalink
Al retornar los datos apuntados por un puntero y imprimirlos me da un
error de Segmentation Default...
Como puedo retornar la informacion que apunta el puntero sin que me el
error ??


Gracias de antemano....



#include <stdio.h>
#include "FGLib.h"

int main(void)
{
char tmp;
tmp = FGLib_UnCads("AaAaAaAaAaAaAaAaAaAaAaA","BbBbBbBbBbBbBbBbBbBbBbBbBb");
printf("%s", tmp);
}



// ------------------- FGLib.h --------------------

char FGLib_UnCads(char *, char *);

char FGLib_UnCads(char *Cad1, char *Cad2)
{
char *UnirCads;

for(int tmp = 0; tmp < FGLib_Len(Cad1) ; tmp++) {
UnirCads[tmp] = Cad1[tmp];
}

for(int tmp = 0; tmp <= FGLib_Len(Cad2); tmp++) {
UnirCads[ FGLib_Len(Cad1) + tmp] = Cad2[tmp];
}

UnirCads[ (FGLib_Len(Cad1) + FGLib_Len(Cad2)) ] = '\000';
return *UnirCads; // <-------------
}
znôrt
2004-01-22 11:20:19 UTC
Permalink
Post by AntyDesk
char *UnirCads;
for(int tmp = 0; tmp < FGLib_Len(Cad1) ; tmp++) {
UnirCads[tmp] = Cad1[tmp];
Aquí no has reservado espacio para UnirCads. La primera en la frente,
es aquí donde te debe dar el segmentation fault. :-)
Post by AntyDesk
UnirCads[ FGLib_Len(Cad1) + tmp] = Cad2[tmp];
Está mal. Primero, obtienes cada vez FGLib_Len(Cad1), y le sumas tmp
que a la vez se va incrementando. Eso tiene dos problemas:

1. La primera vez que añades un carácter a Cad1, pirdes la certeza de
que acabe en '\0' (porque lo estás machacando, con lo que el próximo
FGLib_Len(Cad1) cascará (seg fault).

2. Aunque funcionara, FGLib_Len(Cad1) siempre dará la longitud de la
cadena en cada momento (se incrementará en 1 en cada paso), pero luego
le sumas tmp, que también se incremente y vale 0, 1, 2, 3 etc. y por
tanto la suma apuntará más allá del final de la cadena (y cada vez más
lejos :D)

Una alternativa es obtener el final de la cadena al principio y
simplemente incrementar la posición donde añades (asegúrate de que
escribes en memoria previamente obtenida).

int l = FGLib_Len(Cad1)
for ...
... UnirCads[l++] ...

En general deberías revisar eso de arriba a abajo. Primero, asegúrate
de tener espacio donde copiar las cadenas. Segundo, si lo que
devuelves es una nueva cadena que ocupa espacio de memoria obtenido
por la función, cuando hayas terminado de usar esa cadena (que asignas
a tmp), deberías liberarla explícitamente o tendrás un "mermory leak".

Esto evidentemente es un ejercicio, ya que lo que haces ya lo
implementan las funciones strlen y strcat de la librería estándar.
Como ejercicio ya está bien, pero una vez lo tengas claro, te
recomendaría que lo reescribieras usando aritmética de punteros, para
aprender, y finalmente lo tires a la papelera y uses strcat y strlen
que para eso están.

saludos
znôrt
AntyDesk
2004-01-22 12:40:36 UTC
Permalink
Pero si el printf( ...) lo pones dentro de la funcion antes del return te
imprime las dos cadenas unidas eso quiere decir que el problema es al
retornar. no ?
RETECAL nos tima - MechaKaiser
2004-01-22 12:52:07 UTC
Permalink
O al intentar usar el printf, o a saber donde. Si usas memoria sin haberla
pedido antes, los resultados son desconocidos. Así de simple.
RETECAL nos tima - MechaKaiser
2004-01-22 13:08:52 UTC
Permalink
Mirando el programa más a fondo veo errores graves:

#include <stdio.h>
#include "FGLib.h"

int main(void)
{
char tmp;
tmp = FGLib_UnCads
("AaAaAaAaAaAaAaAaAaAaAaA","BbBbBbBbBbBbBbBbBbBbBbBbBb");
printf("%s", tmp);
//FALLO GRAVE: tmp es de tipo char, no puntero a cadena
}



// ------------------- FGLib.h --------------------

char FGLib_UnCads(char *, char *);

char FGLib_UnCads(char *Cad1, char *Cad2)
{
char *UnirCads;

for(/* Esto es de c++, no c*/int tmp = 0; tmp < FGLib_Len(Cad1) ;
tmp++) {
UnirCads[tmp] = Cad1[tmp];
//FALLO GRAVE: estás usando una variable sin inicializarla
}

for(/* Esto es de c++, no c*/int tmp = 0; tmp <= FGLib_Len(Cad2);
tmp++) {
UnirCads[ FGLib_Len(Cad1) + tmp] = Cad2[tmp];
//FALLO GRAVE: estás usando una variable sin inicializarla
}

UnirCads[ (FGLib_Len(Cad1) + FGLib_Len(Cad2)) ] = '\000';
//FALLO GRAVE: estás usando una variable sin inicializarla

return *UnirCads; // <-------------
//FALLO GRAVE: FGLIB_UnCads devuelve un char, no un puntero
}

Te ha tenido que dar un montón de warnings este programa, del estilo de
"type mismatch" y cosas así. Posible solución: (ojo a las correciones)

#include <stdio.h>
#include "FGLib.h"

int main(void)
{
char *tmp;
tmp = FGLib_UnCads
("AaAaAaAaAaAaAaAaAaAaAaA","BbBbBbBbBbBbBbBbBbBbBbBbBb");
printf("%s", tmp);
free(tmp);
}



// ------------------- FGLib.h --------------------

char FGLib_UnCads(char *, char *);

char * FGLib_UnCads(char *Cad1, char *Cad2)
{
char *UnirCads;
int tmp;

UnirCads=(char *)malloc((FGLib_Len(Cad1) + FGLib_Len(Cad2) + 1) *
sizeof(char));

for(tmp = 0; tmp < FGLib_Len(Cad1) ; tmp++) {
UnirCads[tmp] = Cad1[tmp];
}

for(tmp = 0; tmp <= FGLib_Len(Cad2); tmp++) {
UnirCads[ FGLib_Len(Cad1) + tmp] = Cad2[tmp];
}

UnirCads[ (FGLib_Len(Cad1) + FGLib_Len(Cad2)) ] = '\000';

return UnirCads;
}
RETECAL nos tima - MechaKaiser
2004-01-22 13:10:43 UTC
Permalink
char * FGLib_UnCads(char *, char *);
AntyDesk
2004-01-22 13:26:09 UTC
Permalink
he cambiado lo que me decias y ya me funciona la funcion pero no entiendo
lo que me decias que las variables no las habia inicializado... que
te referias ??

las declaro y las uso, no?



Un saludo y gracias....
RETECAL nos tima - MechaKaiser
2004-01-22 14:39:14 UTC
Permalink
Post by AntyDesk
he cambiado lo que me decias y ya me funciona la funcion pero no entiendo
lo que me decias que las variables no las habia inicializado... que
te referias ??
las declaro y las uso, no?
Una variable, un programa o casi lo que quieras tiene nombre, tipo y valor.
En este caso la variable UnirCads tiene de nombre 'UnirCads', de tipo
puntero a char (char *), pero no tiene valor, y aún así la usas en la
función. Antes de usarla, la tienes que dar valor, por ejemplo con el
malloc que te he puesto. Malloc devuelve un puntero a una región de memoria
reservada para tu programa, por tanto una región válida que puedes
utilizar. Esta región tiene como propiedades, que es de tu programa, que
tiene por tamaño el parámetro que le pasaste a malloc y que no pisa otros
datos importantes (al menos si han sido declarados correctamente). Por
tanto, después de la asignación del malloc UnirCads tiene un valor
correcto, y puede ser utilizado.

Otra cosa, el free(tmp) del main hace lo contrario que el malloc, devuelve
la memoria pedida con el malloc al sistema operativo, para que pueda ser
utilizada por otro proceso, o en otras posibles peticiones de tu programa.
Post by AntyDesk
Un saludo y gracias....
Enga, a programar y a leer, que no es malo (en general ;-)
javuchi
2004-02-11 03:53:14 UTC
Permalink
Post by AntyDesk
char tmp;
¿char tmp o char *tmp?

Loading...