Estoy haciendo un programa en el cual se pide en un principio que se creen 4 áreas de memoria compartida (3 áreas para almacenar una matriz en cada una de ellas y una 4 área para el resultado del ejercicio). A continuación, se nos dice que tenemos que leer una matriz A de un fichero A y una matriz B de un otro fichero B y almacenar ambas matrices en dos de las áreas de memoria compartida creadas (los ficheros son pasados como parámetros por la linea de comandos).
Mi problema es que no soy capaz de leer la matriz A y la B con su respectivo almacenamiento. Lo que he logrado es que sea capaz de hacer o la lectura con la matriz A y su almacenamiento, o bien la lectura con la matriz B y su almacenamiento (de aqui que la ultima linea de codigo del main este comentada, si se deja como codigo y no como comentario se produce una violacion del segmento).
Agradeceria cualquier ayuda. Muchas gracias.
PD1: como restriccion del ejercicio, para leer del fichero solo me dejan utilizar system calls como open, write, read... En ningun momento se puede utilizar fscanf, fprintf....
PD2: la matriz (siempre es cuadrada) esta alojada en el fichero con el siguiente formato:
1;2;3
4;5;6
7;8;9
Código C:
Ver original
#include <stdio.h> #include <stdlib.h> #include <sys/shm.h> #include <sys/ipc.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <string.h> void pintaMensaje(char texto[], int longitud, int salida); //Salida 1: salida estandar / 2 salida error void creaMemCompartida(int numFilas, int resultados[]); int indice(int i, int j, int numColumnas); void inicializaMatriz(int idFichero, int mat[], int numFilas); int main(int arg, char *argv[]) { //Comprobamos si el numero de parametros pasados es correcto if(arg!=6) { char mensaje[]= "ERROR, el programa debe recibir 5 parametros"; pintaMensaje(mensaje, sizeof(mensaje),2); } //Almacenamos los numeros que recibimos como inputs int numFilas= strtol(argv[4],NULL,10); //strtol convierte de string a int -> strtol(string,endptr,base) //Creamos la memoria compartida que utilizaremos int resultados[4]; creaMemCompartida(numFilas,resultados); //Una vez creada la memoria, hacemos que uno de nuestros punteros apunten a la zona de memoria //recien creada. Para ello invocamos a la funcion shmat, pasandole el id obtenido anteriormente //y un par de parametros que en nuestro caso no nos interesan, por tanto basta con ponerlos a 0 int *matA=NULL; int *matB=NULL; int *matC=NULL; int *sumaTotal=NULL; matA= (int *)shmat(resultados[0],0,0); matB= (int *)shmat(resultados[1],0,0); matC= (int *)shmat(resultados[2],0,0); sumaTotal= (int *)shmat(resultados[3],0,0); if(matA==NULL || matB==NULL || matC==NULL || sumaTotal==NULL) { char mensaje[]="ERROR, no se ha conseguido la memoria compartida"; pintaMensaje(mensaje, sizeof(mensaje),2); } /* Abrimos los files de la matriz A y B que tenemos que leer */ int ficheroA = open (argv[1], O_RDONLY); int ficheroB = open (argv[2], O_RDONLY); if(ficheroA<0 || ficheroB<0) { char mensaje[]="ERROR, no se han podido abrir los ficheros de las matrices A y B"; pintaMensaje(mensaje, sizeof(mensaje),2); } inicializaMatriz(ficheroA, matA,numFilas); // inicializaMatriz(ficheroB, matB,numFilas); } void inicializaMatriz(int idFichero, int mat[], int numFilas) { int matriz[numFilas][numFilas]; int i; int j; char buffer[1024]; char *aux; while (read(idFichero, buffer, 1024)!=0) { while(aux!=NULL) { j++; } j=0; i++; } for(i=0; i<3; i++) { for(j=0; j<3; j++) { mat[indice(i,j,numFilas)]= matriz[i][j]; } } } void pintaMensaje(char texto[], int longitud, int salida) { write(salida, texto, longitud); write(salida, "\n", 1); //Imprimimos un salto de linea para una mejora de la interfaz } void creaMemCompartida(int numFilas, int resultados[]) { //Obtenemos claves para las partes de memoria compartida //Todos los procesos que quieran compartir la memoria, deben obtener la misma clave, por esto utilizamos la funcion ftok //Esta funcion recibe un fichero cualquiera que exista y que sea accesible (todos los procesos deben pasar el mismo fichero) y un entero cualquiera (todos los procesos el mismo entero) key_t claveA= ftok("/bin/ls",30); key_t claveB= ftok("/bin/ls",31); key_t claveC= ftok("/bin/ls",32); key_t claveSuma= ftok("/bin/ls",33); if(claveA==-1 || claveB==-1 || claveC==-1 || claveSuma==-1) { char mensaje[]= "ERROR, no se ha conseguido la clave para la memoria compartida"; pintaMensaje(mensaje, sizeof(mensaje),2); } //Creamos la memoria con la clave recien conseguida. Para ello llamamos a la funcion //shmget pasandole la clave, el tamanho de memoria que queremos reservar en bytes y unos flags //Los flags son los permisos de lectura/escritura/ejecucion para propietario, grupos y otros //y el flag IPC_CREAT para indicar que cree la memoria //La funcion devuelve un identificador para la memoria recien creada int id_matA= shmget(claveA, sizeof(int)*numFilas*numFilas, IPC_CREAT|0777); int id_matB= shmget(claveB, sizeof(int)*numFilas*numFilas, IPC_CREAT|0777); int id_matC= shmget(claveC, sizeof(int)*numFilas*numFilas, IPC_CREAT|0777); int id_suma= shmget(claveSuma, sizeof(int), IPC_CREAT|0777); if (id_matA ==-1 || id_matB ==-1 || id_matC ==-1 || id_suma ==-1) { char mensaje[]= "ERROR, no se ha conseguido ID para la memoria compartida"; pintaMensaje(mensaje, sizeof(mensaje),2); } resultados[0]= id_matA; resultados[1]= id_matB; resultados[2]= id_matC; resultados[3]= id_suma; } int indice(int i, int j, int numColumnas) { return j*numColumnas+i; }