[C] Tratando de crear array de strings

Iniciado por huchoko, 8 Junio 2019, 20:54 PM

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

RayR

Serviría tener más datos, como ya te indicaron. Sin embargo, hay unas cuantas cosas claramente incorrectas. Por ejemplo, ¿cómo vas a saber cuántos elementos termina teniendo file_names_in_dir? Lo declaraste con tamaño de 16, pero podría terminar con menos. Por ejemplo, si el directorio que estás explorando sólo tiene 10 entradas válidas, a partir de esa posición, el arreglo contendrá punteros inválidos. Si intentas imprimir 16, obviamente se van a producir errores. Peor aún, si esta línea resulta ser true cuando i vale 0:

if (drce[i].file_name[0] == 0x00) {

Se ejecutará el break, con lo que file_names_in_dir estará vacío, así que en cuanto trates de imprimir cualquiera de sus elementos habrá problemas. Finalmente, ¿qué pasa si el directorio contiene, digamos, 30 archivos? Vas a estar almacenando datos en file_names_in_dir[16] hasta file_names_in_dir[29], que no son posiciones válidas, por lo que estarás sobrescribiendo memoria ocupada probablemente por otras variables del programa. Para empezar deberías hacer cambios como que read_directory devuelva un int (o size_t, o lo que quieras) indicando el número de elementos que realmente termina teniendo file_names_in_dir. Y verifica que no te pases del límite. En esencia, haz estos cambios:

int read_directory(void)
{
...
...
if (aaa < 16) {
    file_names_in_dir[aaa] = drce[i].file_name;
    ++aaa;
}
}
return aaa;
}


Ni idea de donde salio la ultima string, talvez sucedio la gran casualidad que entre en la memoria de otro proceso que tiene ese string.

Imposible. Todos los sistemas operativos modernos aíslan los procesos, por lo que no hay manera de acceder a la de otro de forma accidental.

huchoko

Bien, ha vuelto a funcionar otra vez milagrosamente y espero que no se vuelva a romper.
El tema es este ahora:
printf("\nFile %s", s[2])
Se ejecuta 3 veces mas sin razón aparente, sin estar dentro de ningún ciclo (for, while, do-while...)
Cuando se ejecuta esas 3 veces mas no imprime el elemento que está en s[2], pero la primera vez si. No es el problema que no se imprima las tres veces, es por que se ejecuta tres veces esa línea sin razón aparente

/* Problema solucionado con padding */
char* s[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void read_directory(void)
{
/* Read the directory */
hd_read(start_of_root, FAT32_FILES_PER_DIRECTORY * sizeof(struct DirectoryEntry), (uint8_t*)&drce[0]);

int aaa = 0;
for (int i = 0; i < FAT32_FILES_PER_DIRECTORY; ++i) {
if (drce[i].file_name[0] == 0x00) {
printf("\n-- END --\n");
break;
}
/* File has a long file name */
if ((drce[i].attributes & 0x0F) == 0x0F) {
s[i] = 0;
continue;
}

/* "File" is a directory */
if ((drce[i].attributes & 0x10) == 0x10){
printf("Directory name: %s\n", drce[i].file_name);
s[i] = 0;
continue;
}

/* If the first byte of file_name is 0xE5, means that the file is deleted */
if (drce[i].file_name[0] == FAT32_DELETED_FILE)
continue;
/* This should print the names of the files that are in the root directory... */
printf("File name: %s, %i bytes.\n", drce[i].file_name, drce[i].file_size);
s[aaa] = drce[i].file_name;
++aaa;
++files_in_directory;
}
}

void read_bpb(uint32_t offset)
{
/* Read the BPB (BIOS parameter block) - Lee el BPB (Bloque de parámetros de la BIOS) */
hd_read(offset, FATBPB_SIZE, (uint8_t*)&bpb);

fat_start = (offset + bpb.reserved_sectors);
fat_size = bpb.sectors_per_fat;
start_of_data = fat_start + (fat_size * bpb.fats_number);
start_of_root = start_of_data + ((bpb.cluster_root - 2) * bpb.sectors_per_cluster);
root_dir_sects = ((bpb.root_dir_entries * 32) + (bpb.bytes_per_sector - 1) / bpb.bytes_per_sector);
data_sects = (bpb.reserved_sectors + bpb.fats_number * (bpb.sectors_per_fat + root_dir_sects));
cluster_count = data_sects / bpb.sectors_per_cluster;

read_directory();
printf("\nFile %s", s[2]); /* Se ejecuta 3 veces sin razon */
}

RayR

Cita de: hextakatt en  9 Junio 2019, 00:33 AM
Bien, ha vuelto a funcionar otra vez milagrosamente

Ése es el sello distintivo de un error de memoria. Un programa con un problema así a veces funciona y a veces no. Las cosas no se arreglan por arte de magia. Si el programa no funciona siempre, tiene un error. No hay más.

Esto:

/* Problema solucionado con padding */
char* s[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};


No soluciona nada. De hecho, no cambia nada. Las variables globales no inicializadas explícitamente, son automáticamente inicializadas a 0 (en el caso de los arreglos, todos sus elementos son inicializados a 0). Es decir, exactamente eso que hiciste ahí, el compilador ya lo hacía por ti antes.

Y ya te mencioné al menos 3 casos en los que tienes garantizado que tu programa fallará, y es probable que alguno de ellos se esté dando y es lo que te está causando problemas., por lo que hay la posibilidad de que las modificaciones que te puse lo solucionen. No lo garantizo, obviamente, pero es posible. Si no lo intentas ni sigues nuestras sugerencias, no hay mucho más que hacer.

huchoko

No es que no lo haya tratado, publicaste tu respuesta cuando estaba escribiendo la mía, perdón por eso.
La razón de por que se repite cuatro veces es por que la función read_bpb se ejecutaba 4 veces por un for.
Problema solucionado, gracias y perdón por gastar su tiempo.
Saludos.

RayR

Nah, no pasa nada. Los que estamos aquí es porque nos gusta tratar de ayudar/colaborar. Es sólo que a veces hay gente que pida ayuda, y cuando se les da una opción la rechazan sin probar. Me ha tocado ver usuarios a los que les dan una solución que claramente es correcta, y responden: "mmm, no, no creo que sea eso. Mejor intentaré hacer esto otro...", y dices: ¿entonces para qué #%& piden ayuda?  :P. Pero no es tu caso.

Saludos, y si tienes más preguntas, no dudes en postearlas.