Foros del Web » Programación para mayores de 30 ;) » Programación General »

¿Donde se encuentra el error en este programa de matrices?

Estas en el tema de ¿Donde se encuentra el error en este programa de matrices? en el foro de Programación General en Foros del Web. Este programa es la recreación de un problema que tuve hace algún tiempo. El objetivo es sumar 2 matrices mediante una función Suma, donde las ...
  #1 (permalink)  
Antiguo 13/06/2005, 17:46
Avatar de spike_jr  
Fecha de Ingreso: febrero-2005
Ubicación: Valencia
Mensajes: 114
Antigüedad: 19 años, 9 meses
Puntos: 2
¿Donde se encuentra el error en este programa de matrices?

Este programa es la recreación de un problema que tuve hace algún tiempo.

El objetivo es sumar 2 matrices mediante una función Suma, donde las matrices son arreglos bidimensionales creados dinámicamente y su orden es ingresado desde el teclado.

Pero resulta que el programa no muestra errores a la hora de compilar, talvez algunos warnings, pero al momento de ejecutar el exe, sucede alguno de los siguientes casos:
-El programa se cuelga desde el inicio;
-Muestra bien el resultado, pero al final se cuelga;
-Muestra bien el resultado, pero al final muestra el mensaje de error:
Null pointer assignment.
-Muestra bien el resultado pero solo para matrices de orden pequeño;

No se porque se cuelga ni donde puede estar el error. Si alguien es tan amable de hecharle un vistazo lo agradeceria mucho.
Aqui dejo el codigo:

Código:
#include <iostream.h>
#include <stdlib.h>
#include <time.h>

//Asigna Memoria a un puntero doble A
void CrearMatriz( int **A, int Orden);

//Destruye la matriz cuadrada creada con CrearMatriz
void DestruirMatriz( int **A, int Orden);

//Retorna la matriz suma de A y B
int **Suma( int **A, int **B, int Orden );

//Muestra la matriz A
void MostrarMatriz( int **A, int Orden );

void main()
{

 //2 punteros dobles, se utilizarán para crear 2 arreglos bidimensionales
 //dinámicos
 int **a,**b;

 int i,j;

 int N;

 cout<<"\n\nIngrese el orden de las matrices: ";
 cin>>N;

 CrearMatriz(a,N); //se crea dinámicamente una MATRIZ de orden N
 CrearMatriz(b,N); //se crea dinámicamente una MATRIZ de orden N

 srand(time(NULL)); //Inicializa el generador números aleatorios,
		    //dependiente del tiempo actual

 for(i=0;i<N;i++)
  for(j=0;j<N;j++)
  {
   a[i][j]=rand()%10; // a y b contienen números naturales menores que 10
   b[i][j]=rand()%10;
  }

 cout<<"\nContenido de matriz A:\n";
 MostrarMatriz(a,N); //se muestra la matriz A

 cout<<"\n\nContenido de matriz B:\n";
 MostrarMatriz(b,N); //se muestra la matriz B

 a=Suma(a, b, N); //se ejecuta la función suma y se asigna el
                  //resultado a la matriz a

 cout<<"\n\nLa suma matricial de A y B es:\n";
 MostrarMatriz(a,N); //se muestra la suma A+B

 DestruirMatriz(a, N); //destruye A
 DestruirMatriz(b, N); //destruye B

}

void CrearMatriz( int **A, int Orden)
{
     for( int i=0; i<Orden; i++)
         A[i] = new int[Orden];
}

void DestruirMatriz( int **A, int Orden)
{
     for( int i=0; i<Orden; i++)
         delete A[i];
}

int **Suma( int **A, int **B, int Orden )
{
     int **C,i,j;

     CrearMatriz(C,Orden);

     for(i=0;i<Orden;i++)
          for(j=0;j<Orden;j++)
               C[i][j]=A[i][j]+B[i][j];

     return C;
}

void MostrarMatriz( int **A, int Orden )
{
     int i,j;

     for(i=0;i<Orden;i++)
     {
           cout<<"\n";
           for(j=0;j<Orden;j++)
                 cout<<A[i][j]<<" ";
     }
}
Cita:
"La programación es una carrera entre ingenieros de software luchando para construir programas cada vez más grandes, mejores y a prueba de idiotas, y el universo intentando producir cada vez más grandes y mejores idiotas. por ahora, gana el universo." ( Rich Cook )
  #2 (permalink)  
Antiguo 13/06/2005, 23:11
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 7 meses
Puntos: 17
Fácil.

a[j]=rand()%10;

Estás cargándote los punteros bestialmente...
  #3 (permalink)  
Antiguo 14/06/2005, 01:18
Avatar de spike_jr  
Fecha de Ingreso: febrero-2005
Ubicación: Valencia
Mensajes: 114
Antigüedad: 19 años, 9 meses
Puntos: 2
¿Por qué?

Gracias por responder.

Primero que todo me he dado cuenta que el compilador que utiliza el Devcpp 4 está algo desfasado porque al compilar este programa no me daba ningun error de compilación y en cambio hoy lo he compilado con el g++ version 3.3.4 y me ha dado los siguientes errores:

1.- error: `main' must return `int'
2.- In function `int main(...)':
matrices.cpp:40: error: invalid conversion from `int' to `int*'

El primero lo entiendo pero no lo entiendo. Vamos a ver, para que me dice que la función main debe devolverme un 'int' si la tengo definida como 'void main()' ? Lo he solucionado obviamente definiendola como 'int main()' y return 0. Pero no me queda claro el error.

El segundo se refiere al error que tu bien has mencionado

a[j]=rand()%10;

Es porque al ser una matriz se le tiene q asignar los valores de esta manera? por ejemplo:

a[j][j] =rand()%10;

En cualquier caso, lo he modificado le ha asignado los valores como una matriz. Me compila sin problemas, pero al ejecutar es cuando se cuelga.

Y ahora ya si que no se porque.


Cita:
"La programación es una carrera entre ingenieros de software luchando para construir programas cada vez más grandes, mejores y a prueba de idiotas, y el universo intentando producir cada vez más grandes y mejores idiotas. por ahora, gana el universo." ( Rich Cook )
  #4 (permalink)  
Antiguo 14/06/2005, 01:35
 
Fecha de Ingreso: octubre-2004
Mensajes: 2.627
Antigüedad: 20 años, 1 mes
Puntos: 48
¿Donde reservas la memoria para el array? Porque solo veo un A[i]= new int[Orden], pero en ningun sitio veo que reserves para A.
  #5 (permalink)  
Antiguo 14/06/2005, 01:42
Avatar de spike_jr  
Fecha de Ingreso: febrero-2005
Ubicación: Valencia
Mensajes: 114
Antigüedad: 19 años, 9 meses
Puntos: 2
what???

Como???

void CrearMatriz( int **A, int Orden)
{
for( int i=0; i<Orden; i++)
A[i] = new int[Orden];
}

En los argumentos de la funcion le paso 'A' como se ve es una matriz y despues le reservo memoria a cada elemento con A[i] = new int[Orden]

Gracias por echarle un vistazo DarkJ, pero creo q el error no esta ahi... creo.
  #6 (permalink)  
Antiguo 14/06/2005, 06:06
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 7 meses
Puntos: 17
Puf puf, no vi el segundo error, que también es cierto, supuse que las funciones auxiliares estaban bien, porque las soléis sacar de otros sitios. Tienes en total 5 errores.

Lo primero, tienes un doble puntero. Primero necesitas reservar memoria para A y luego para cada unno de los punteros que acabas de crear.

Segundo, para usar la matriz usas a[i][j], nada de a[i]. Si te das cuenta, a es el array de los PUNTEROS que a su vez son arrays de ints, por lo tanto lo que modificas de esa manera son los PUNTEROS.

Tercero, al liberar los punteros, en el bucle debes hacer delete [] a[i], lo que elimina todo el array. Son cosas diferentes

a = new int -> delete a
a = new int[] -> delete [] a

En cambio, lo que tú haces es:

a = new int[] -> delete a

Cuarto, al igual que al crear la matriz, al destruirla, despues de hacer el bucle que libera los punteros, debes liberar el puntero de los punteros, o sea a, con delete [] a.

Quinto, estás haciendo a=Suma(a,b,N). Como Suma() crea una matriz nueva dentro de ella, y luego la asignas a "a", estás perdiendo el puntero a "a", y por tanto al final del programa queda sin eliminar. Quizás piensas que poner esa línea lo que hace es sustituir la matriz "a" ya sumada por la "a" original, pero NO. Estás SUSTITUYENDO los PUNTEROS, no la MATRIZ. Para hacer cosas de ese estilo se tendrían que usar clases, en las que pueden definir los comportamientos, pero no punteros dado que estás creyendo que tu "int **" es una matriz que la puedes usar como un objeto, cuando en realidad es un simple puntero.
  #7 (permalink)  
Antiguo 14/06/2005, 06:08
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años, 7 meses
Puntos: 17
Cita:
Iniciado por spike_jr
Gracias por responder.

Primero que todo me he dado cuenta que el compilador que utiliza el Devcpp 4 está algo desfasado porque al compilar este programa no me daba ningun error de compilación y en cambio hoy lo he compilado con el g++ version 3.3.4 y me ha dado los siguientes errores:

1.- error: `main' must return `int'
2.- In function `int main(...)':
matrices.cpp:40: error: invalid conversion from `int' to `int*'

El primero lo entiendo pero no lo entiendo. Vamos a ver, para que me dice que la función main debe devolverme un 'int' si la tengo definida como 'void main()' ? Lo he solucionado obviamente definiendola como 'int main()' y return 0. Pero no me queda claro el error.

El segundo se refiere al error que tu bien has mencionado

a[j]=rand()%10;

Es porque al ser una matriz se le tiene q asignar los valores de esta manera? por ejemplo:

a[j][j] =rand()%10;

En cualquier caso, lo he modificado le ha asignado los valores como una matriz. Me compila sin problemas, pero al ejecutar es cuando se cuelga.

Y ahora ya si que no se porque.
"int main" es la definición ANSI C portable, la cual deberías cumplir. main siempre devuelve un valor al sistema o al código que lo ejecuta, etc. Puedes poner void main en C++, aunque no deberías, pero en cualquier caso se transforma en int main y return RETORNO_SIN_ERROR, o parecido, peusto que cualquier programa devuelve un valor.
  #8 (permalink)  
Antiguo 14/06/2005, 07:40
Avatar de spike_jr  
Fecha de Ingreso: febrero-2005
Ubicación: Valencia
Mensajes: 114
Antigüedad: 19 años, 9 meses
Puntos: 2
that's ok

Pues si que... vaya por dios q mal.

Sobre la funcion 'suma' tienes razón que al devolver una matriz machaco el puntero a 'a'.
Lo que he hecho es crearme otra matriz en main 'int **aux' por ejemplo, le reservo memoria con aux = new int*[tam] y le asigno lo que me devuelve la funcion suma.

Antes de hacer eso tambien me funcionaba bien el programa, pero supongo que la zona de memoria donde apuntaba 'a' se quedaba en el aire y solo 'destruia' b y c. Y aunque funcione no creo q este bien dejar cosas por ahi divagando. Así q gracias por tu ayuda q me ha servido de mucho

------------------------------------------
Si los programadore cazaran...elefantes:

Cita:
Programador Assembler.

No los cazan, crean sus propios elefantes, mas rápidos y pequeños.
Cita:
Programador VISUAL BASIC.

Con el mouse dan doble-click en los rifles, dan doble-click en las balas, dan doble-click en el elefante. Esto realmente divierte tanto al elefante que lo hace revolcarse de risa por el suelo y aplasta el mouse. Mientras, el programador VISUAL BASIC se queda mirando como el elefante se aleja tranquilamente.
Cita:
Programador C++

Toman un elefante abstracto y derivan de el un nuevo elefante (ej. MiElefante) con todas las propiedades que necesitan. Para cazar uno simplemente, una instancia class Cazador, llama al método CazarElefante el cual la envía el mensaje CAZAR a la class Elefante que lo entiende con un método virtual puro, cuya implementacion esta definida en la nueva clase derivada MiElefante. Esta implementación llama al método setEstoyCazado() que pone el atributo bEstoyCazado =TRUE, con lo que el elefante se da por enterado que ha sido cazado. La class MiElefante esta disponible para ser rehusada/extendida por otro proyecto, ventajas de la OOP.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 22:57.