Confusión: arreglo de arreglo de strings (o con punteros)

Iniciado por Skali, 18 Mayo 2018, 16:32 PM

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

Skali

Buenas, me estoy haciendo un lio barbaro con los tipos en C. Estoy trabajando con strings y MPI. Necesito una variable que almacene un array de textos, en la que cada texto sería un array de strings, en el que cada string es un array de char...

Cada proceso worker necesita encontrar las 5 palabras que más aparecen en un texto. Hasta ahora lo que podría hacer es:

char palabrasQueMasAparecen[5][tamanioPalabra];

o bien:

char *palabrasQueMasAparecen[5];

for(int palabra=0; palabra<5; palabra++) {
     palabrasQueMasAparecen[palabra] = (char *) malloc(sizeof(char) * tamanioPalabra);
}


El asunto es que necesito almacenar en una misma variable, las palabras que más aparecen de cada uno de los procesos. Entonces pensé en algo como:

char palabrasQueMasAparecen[cantProcesos][5][tamanioPalabra];

o bien:

char *palabrasQueMasAparecen[cantProcesos][5];

for(int proceso=0; proceso<5; proceso++) {
for(int palabra=0; palabra<5; palabra++) {
palabrasQueMasAparecen[proceso][palabra] = (char *) malloc(sizeof(char) * tamanioPalabra);
}
}


El problema es que cada proceso tiene que enviar las 5 palabras que más usa al proceso maestro, a través de la función MPI_Send(), cuyo primer parámetro es la dirección de un buffer.

Como cada proceso debería enviar sus 5 palabras, yo pensé que cada uno debería enviar como primer parámetro de ésta función:

&palabrasQueMasAparecen[idProceso];


pero el programa está crasheando cuando lo quiero correr, y estoy seguro de que estoy usando mal los tipos, y estoy enviando mal el primer parámetro a dicha función... Necesitaría que me den una idea de como usar los tipos correctamente para resolver éste problema.

Muchas gracias desde ya!

MAFUS

#1
Si lo haces con arrays de punteros
char* miArray[5]
deberás usar *alloc para conseguir dimensionar memoria antes de guardar una cadena en ella. Y cuando acabes con esas cadenas destruirlas con free. A lo mejor se te rompe por eso.

En cambio si todo son arrays ya tienes la memoria dimensionada, pero a diferencia de los punteros dimensionados con *alloc su ámbito empieza en la función que los declaró, ten presente eso.

Sea como sea a la hora de entregar palabras recuerda que tanto punteros como arrays se comportan como punteros y una función que espere un char* muy amablemente va a acoger un array:
Tanto si has hecho
char* miArray[AGENTE][PALABRAS]
cómo
char miArray[AGENTE][PALABRAS][LETRAS]
puedes pasar a la función que espera un char*
MiFuncion(miArray[nAgente][nPalabra])

Skali

Hola MAFUS! Gracias nuevamente por tu atención, es muy valorada! Siempre me haces dar cuenta que estoy planteando las cosas bien y que el error esta en otro lugar. Ahora me está funcionando con arreglos de 3 dimensiones. De tanto que toquetié la verdad que no se donde estaba el error, pero seguro me equivoque declarando mal otra variable o algo...

Aprovechando ésta situación, me gustaría preguntarte cuál es la manera más simple para depurar el código cuando crashea. Corregir los errores que devuelve el compilador suele ser facil, pero cuando ocurre algun segmentation fault o crasheos similares, cuál sería el procedimiento mas facil para chequear el código en busca del culpable?

Muchisimas gracias nuevamente.

Saludos!

MAFUS

Seguramente usar el depurador y situar breakpoints cerca de dónde posiblemente esté el fallo. Pero yo no uso. En mi caso hago que la aplicación escriba en stderr, que no pasa por ningún buffer y escribe directamente en la pantalla. Voy situándolos cerca de dónde creo que podría estar el fallo. Y si con eso no lo resuelvo empiezo desde el main para ir recorriendo las llamadas a funciones y llegar hasta el fallo. ¡

La verdad, me da pereza aprender a usar el depurador, ya lo hago yo con stderr, jajaja.