C extraño error con strcpy e incluso una solución más extraña

Estoy creando un programa para abrir archivos .txt en un directorio determinado, tengo una matriz con todas las rutas absolutas de los archivos dentro del directorio en cuestión y estoy creando una función para extraer y devolver el nombre de los archivos, la función se escribe de la siguiente manera:

char *name(char *string) {
    int i = strlen(string);
    char *aux;
    while(string[i-1] != '/'){
        i--;
    }
    strcpy(aux, &string[i]); 
    return aux;
}

La función anterior está dando un error de falla de segmentación, pero si agrego la siguiente línea "int j = 0;" antes de la declaración de aux, el error desaparece, el código nuevo y funcional es

char *name(char *string) {
    int i = strlen(string);
    int j = 0;
    char *aux;
    while(string[i-1] != '/'){
        i--;
    }
    strcpy(aux, &string[i]); 
    return aux;
}

entrada: C:\prueba\a.txt
salida: a.txt

¿Por qué la adición de "int j = 0;" resuelve el problema? Estoy atascado con eso y no puedo continuar porque no sé si esta inconsistencia podría conducir a problemas mayores más adelante, estoy pensando en escribir mi propia función para copiar las cadenas, pero antes de eso realmente quiero entender eso. error.

preguntado el 01 de julio de 12 a las 05:07

aux no está inicializado. Usa malloc primero. -

otra solución que encontré es intercambiar el orden de las declaraciones "int i = strlen(string);" y "char *aux;" -

@ user1493813, estas no son soluciones. Este es un comportamiento indefinido. -

Además, otra nota al margen, su entrada está especificando barras invertidas, y su bucle está buscando barras diagonales. No tiene ningún terminador de bucle que no sea encontrar una barra diagonal, por lo que también debe fallar en esta entrada. Para estar seguro, ponga un cheque para rescatar i == 0. -

Apoyos para "no puedo continuar porque no sé si esta inconsistencia podría conducir a problemas mayores más adelante" y venir aquí para preguntar en lugar de simplemente continuar después de encontrar algo que "funciona". -

3 Respuestas

nunca asignas aux. aux necesita apuntar a una ubicación de memoria válida antes de intentar copiar algo en ella.

En lugar de char *aux, necesitas algo como char *aux = malloc(i+1);. Tenga en cuenta que i+1 es exagerado porque en tu caso aux siempre será al menos 3 caracteres más corto que string (no contendrá C:\), pero probablemente no le interesen cadenas tan pequeñas. Recuerda free() el puntero una vez que haya terminado con él.

Además, la razón por la que descubrió que funciona cambiando los órdenes de las declaraciones y/o agregando una declaración es probablemente que tuvo suerte y, de alguna manera, la ubicación a la que aux puntos a es válido (si lo hace sólo char *aux;, aux apunta a una ubicación aleatoria). Esto es pura suerte sin embargo, y sigue siendo codigo invalido aunque parece que funciona.

En el futuro, es posible que desee utilizar una herramienta como Valgrind para ayudarle a diagnosticar problemas de memoria. También debe leer un tutorial sobre administración básica de memoria y punteros en C.

Respondido 01 Jul 12, 05:07

strcpy copia el terminador nulo, absolutamente necesita (i+1). - Nick

@Nick: no, no lo haces. aux siempre es más corto que string. - houbysoft

@Nick: explicación agregada para responder en caso de que no fuera obvio. - houbysoft

Sí, me perdí la parte de que siempre usaba rutas absolutas, gracias. - Nick

muchas gracias, he usado un contador en el bucle para contar el número de caracteres y luego hago " char *aux = malloc(cont + 1); ", ahora me doy cuenta de que fue un error de puntero tan tonto, realmente hay que prestar atención a lo básico - user1493813

Dado que parece que solo está interesado en utilizar la parte del nombre de archivo de la cadena como parámetro, otra opción es usar la parte de la cadena que ya tiene.

Prueba: aux = &string[i]; en lugar del strcpy.

Esto le da un puntero a la parte de la cadena que le interesa (es decir, la última parte después de la '/' final).

En segundo lugar, asegúrese de tener un '/' en todas sus cadenas de entrada, de lo contrario, sucederán cosas malas (es decir, su ciclo pasará del comienzo de la cadena, probablemente encuentre una falla de segmentación en algún momento). Sería mejor poner una condición en el ciclo para que no continúe más allá de i = 1.

Respondido 01 Jul 12, 05:07

No asignas ninguna memoria a aux. Está intentando escribir en la memoria a través de un puntero no inicializado.

Respondido 01 Jul 12, 05:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.