C/Visual C - Reserva de Memoria Dinamica Matriz MPI

   
Vista:

Reserva de Memoria Dinamica Matriz MPI

Publicado por ivan (1 intervención) el 28/03/2011 19:47:14
Hola Buenos días:

Estoy haciendo un programa en MPI donde le a cada proceso hijo le pasa un número de lineas de la matriz1 y toda la matriz2 para que realiace calculo parcial y se lo devuelve al proceso padre. El caso es que cuando voy a reservar memoria para las matrices dicho reserva de memoria tiene que ser en bloque no puede ser puntero de un puntero puesto que si no me da error de segmentación. Yo lo estoy haciendo de la siguiente manera:

int **M1=(int**)malloc(filas1 *sizeof(int*));
for (i=0; i<filas1; i++)
{
M1[i]= (int*)malloc(columnas1 *sizeof(int));
}

Pero me dijeron que de esta manera no vale y lo comprobe yo mismo , ya que da error.

También lo he probrado de la siguiente manera:



M1=(int **)malloc(filas1*sizeof(int *));
M1[0]=(int *)malloc(filas1*columnas1*sizeof(int));
for(i=1; i<filas1; i++)
{
M1[i]=M1[i-1]+columnas1;
}

Pero me da el mismo error. Consulte a un profesor de universiad y me dijo que lo hiciera así:

M1=(int *)malloc(filas1*columnas1*sizeof(int));

Pero de esta forma cuando trato M1 en otras partes del codigo como una matriz M1[filas1][columnas1] ni siquiera compila al no reconocerlo como Matriz. Alguien me podría hechar una mano¿?
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Reserva de Memoria Dinamica Matriz MPI

Publicado por Tom (481 intervenciones) el 29/03/2011 15:37:06
El profe tiene razón, si le has contado el problema tan vagamente la única solución aplicable es la que él te ha comentado.


Si en otras partes del código tienes problemas, deberás arreglarlos cada uno en su sitio.

Por cierto, se escribe echar.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Reserva de Memoria Dinamica Matriz MPI

Publicado por eduardo (82 intervenciones) el 30/03/2011 04:27:42
#include <stdio.h>
#include <stdlib.h>

int main()
{
int** tabla;
int filas, columnas;

scanf( "%d%d", &filas, &columnas );
tabla = creaTabla( filas, columnas );

if ( !tabla ) {
perror( "Memoria insuficiente\n" );
return EXIT_FAILURE;
}

/* procesar tabla */

return EXIT_SUCCESS;
}

int** creaTabla( const int fil, const int col )
{
int** p;
register int i;

/* Crear los apuntadores a cada fila */
p = (int**) malloc( fil * sizeof( int* ) );

if ( p == NULL ) return NULL;

/* Crear las columnas para cada fila */
for ( i = 0; i < fil; ++i ) {
p[i] = (char*) malloc( col * sizeof( int ) );
if ( p == NULL ) return NULL;
}

return p;
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Reserva de Memoria Dinamica Matriz MPI

Publicado por Tom (481 intervenciones) el 30/03/2011 11:57:00
Hay un fallo que comete mucha gente (no sé por qué) y es el de asumir que una matriz bidimensional, en c, se debe siempre representar como un puntero a puntero (**).

Hay que tener en cuenta dos cosas:

- Una matriz multidimensional solo puede declararse con dimensiones constantes, conocidas en tiempo de compilación. Hay matices aquí, algún compilador podría permitirte hacer algo así:

int *tabla;
...
procesaTabla(tabla);
...
}
void procesaTabla(int tabla[filas][columnas]) {
...
}

- Una matriz ocupa un espacio contiguo en memoria. Es el compilador el que se encarga de simular las posibles dimensiones de la matriz, usando aritmética simple (exactamente igual que en el código que te pongo a continuación). Por eso, las dimensiones de un array deben ser conocidas durante la compilación.

Hay más de una solución para tu problema, te pego una:

#include <stdio.h>
#include <stdlib.h>


/* */
int main() {
int *tabla, *creaTabla(int, int);
int filas, columnas;
void procesaTabla(int*, int, int);

scanf("%d%d", &filas, &columnas);
tabla = creaTabla(filas, columnas);

if(!tabla) {
perror("Memoria insuficiente\n");
return EXIT_FAILURE;
}

/* procesar tabla */
procesaTabla(tabla, filas, columnas);
return EXIT_SUCCESS;
}
/* */
int* creaTabla(int fil, int col) {
int *p;
register int i;

/* Reservar espacio para la matriz completa */
p = (int*)calloc(fil * col, sizeof(int));

if(p == NULL) return NULL;

return p;
}
/* */
void procesaTabla(int *tabla, int fil, int col) {
int f, c;

for(f = 0; f < fil; f++) {
for(c = 0; c < col; c++) {
tabla[(f * col) + c] = f * 100 + c;
}
}
for(f = 0; f < fil; f++) {
printf("%d - ", f);
for(c = 0; c < col; c++) {
printf("%d ", tabla[(f * col) + c]);
}
printf("\n");
}
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Reserva de Memoria Dinamica Matriz MPI

Publicado por eduardo (82 intervenciones) el 30/03/2011 04:30:53
Edito: en la linea de la función:
p[i] = (char*)malloc( col * sizeof( int ) );

Debió ser:
p[i] = (int*)malloc( col * sizeof( int ) );
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Reserva de Memoria Dinamica Matriz MPI

Publicado por Tom (481 intervenciones) el 30/03/2011 12:24:53
Y si puedes vivir con warnings (a mí me molestan muchísimo) prueba este ejemplo de lo que comentaba antes:

#include <stdio.h>
#include <stdlib.h>

int fil, col;

/* */
void test(int tabla[fil][col]) {
int f, c;

for(f = 0; f < fil; f++)
for(c = 0; c < col; c++)
tabla[f][c] = f * 100 + c;

for(f = 0; f < fil; f++) {
printf("%d - ", f);
for(c = 0; c < col; c++) {
printf("%d ", tabla[f][c]);
}
printf("\n");
}
}
/* */
int main() {
int f, c;
int **tabla = 0;

fil = 5;
col = 7;

tabla = (int **)calloc(fil * col, sizeof(int));
test(tabla);
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Reserva de Memoria Dinamica Matriz MPI

Publicado por eduardo (82 intervenciones) el 02/04/2011 03:29:25
Debo admitir que mi función tiene 2 graves errores. Uno de ellos es que no libera la memoria asignada en caso que no se obtenga memoria para todas la filas, es decir, la filas que si lograron obtener memoria deben liberarse. El segundo es que la comparación del puntero dentro del bucle está mal. Tom, creo que si es posible representar un array bidimensional dinámico usando un doble apuntador. Cuando creamos un vector dinámico, es decir, un vector de una dimensión, la variable puntero apunta al inicio del vector. Si nos proponemos crear un vector de vectores dinámicos, tendríamos que crear los apuntadores al inicio de cada vector (filas) y luego obtener espacio para cada elemento. La función quedaría así:
[code]
int** creaTabla( const int fil, const int col )
{
int** p;
int i;

/* Reservar del bloque de memoria principal */
p = (int**)malloc( fil * sizeof *p );

if ( p ) {
/* Reservar para cada elemento del bloque principal (fila) */
for ( i = 0; i < fil; ++i ) {
p[i] = (int*)malloc( col * sizeof **p );
if ( !p ) break;
}

/* Verificar si se reservó memoria para todas las filas */
if ( i != fil ) {
/* Si no es asi liberamos la memoria asignada */
while ( i-- > 0 )
free( p[i] );

free( p );
p = NULL;
}
}

return p;
}
[/code]
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Reserva de Memoria Dinamica Matriz MPI

Publicado por Tom (481 intervenciones) el 07/04/2011 17:13:02
Eduardo, posible es, por supuesto, y a veces necesario. Pero _no_siempre_.

Es conveniente cuando alguna de las dimensiones no es constante como en un array de cadenas de caracteres de longitud variable ... por ejemplo.

A lo que yo me refería es a la tendencia a asimilar _siempre_ un array bidimensional con un ** (¿una tabla de enteros de 10 dimensiones sería un int********* ?)

Salud!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar