2

Estaba haciendo un programa que crea una matriz y luego hace su matriz transpuesta, cree unas cuantas funciones, compila todo bien, pero al momento de ejecutar me sale error. Supongo que es un problema de mi código.

Cuando llamo hasta esta parte

pedirDatos();
cout<<endl;
imprimirMatriz(p,nFilas,nColumnas);
cout<<endl;//Hasta esta parte todo bien, luego se demora en cargar y me sale error

Me funciona todo bien, luego es cuando falla, parece que es un error de la función convertirTranspuesta

#include <iostream>

using namespace std;

int **p, **transpuesta,nFilas,nColumnas;

void pedirDatos();
void imprimirMatriz(int**,int,int);
void convertirTranspuesta(int**,int,int);

int main(){

    pedirDatos();
    cout<<endl;
    imprimirMatriz(p,nFilas,nColumnas);
    cout<<endl;//Hasta esta parte todo bien, luego se demora en cargar y me sale error
    convertirTranspuesta(transpuesta,nFilas,nColumnas);
    cout<<endl;
    imprimirMatriz(transpuesta,nFilas,nColumnas);

    return 0;
}

void pedirDatos(){
    cout<<"Ingrese el numero de filas: "; cin>>nFilas;
    cout<<"Ingrese el numero de columnas: "; cin>>nColumnas;
    p = new int*[nFilas];
    for(int i=0;i<nFilas;i++){
        p[i] = new int[nColumnas];
    }

    for(int i=0;i<nFilas;i++){
        for(int j=0;j<nColumnas;j++){
            cout<<"Ingrese un numero para la posicion ["<<i<<"]["<<j<<"]: ";
            cin>>*(*(p+i)+j);
        }
        cout<<endl;
    }
}

void imprimirMatriz(int **matriz,int nF,int nC){
    for(int i=0;i<nF;i++){
        for(int j=0;j<nC;j++){
            cout<<*(*(matriz+i)+j)<<" ";
        }
        cout<<endl;
    }
}

void convertirTranspuesta(int **matriz,int nF,int nC){
    transpuesta = new int*[nC];
    for(int i=0;i<nC;i++){
        transpuesta[i] = new int[nF];
    }

    for(int i=0;i<nC;i++){
        for(int j=0;j<nF;j++){
            *(*(transpuesta+i)+j) = *(*(matriz+j)+i);
        }
    }
}
MrDave1999
  • 7,491
  • 1
  • 7
  • 22
Federico Choy
  • 307
  • 1
  • 5

1 Answers1

4

Analicemos esta línea de código:

convertirTranspuesta(transpuesta, nFilas, nColumnas);

Como la variable transpuesta fue declarada como una variable global, el compilador de forma implícita le asigna un NULL y ese es el valor que le pasas al primer parámetro de la función y ahí está el problema, ya que la función convertirTranspuesta intentará desreferenciar el puntero nulo y eso ocasiona que intentes acceder a una dirección (en este caso a la dirección NULL) que al proceso actual no le pertenece, haciendo que el sistema mate el proceso en ese instante.

La solución es sencilla, simplemente debes pasar la dirección de memoria que tenga guardada el puntero p:

convertirTranspuesta(p, nFilas, nColumnas);

Y también estás pasando mal los valores a esta función:

//--> Matriz T = nColumnas x nFilas (matriz transpuesta de A)
//--> Matriz A = nFilas x nColumnas (matriz A)
imprimirMatriz(transpuesta, nFilas, nColumnas);

La matriz transpuesta de A es de MxN y la matriz A (al que apunta p) es de NxM, así que deberías hacerlo así:

imprimirMatriz(transpuesta, nColumnas, nFilas);

¡No olvides de liberar la memoria! ¡De lo contrario tendrás fuga de memoria!

int main()
{

    pedirDatos();
    cout<<endl;
    imprimirMatriz(p,nFilas,nColumnas);
    cout<<endl;
    convertirTranspuesta(p, nFilas, nColumnas);
    cout<<endl;
    imprimirMatriz(transpuesta,nColumnas,nFilas);
    
    //Para liberar cada array al que apunte un puntero.
    for(int i = 0; i != nColumnas; ++i)
        delete[] transpuesta[i];
    for(int i = 0; i != nFilas; ++i)
        delete[] p[i];

    //Para liberar los arrays de punteros.
    delete[] p;
    delete[] transpuesta;
    
    return 0;
}

Observación #1:

En este caso no necesitas usar variables globales, es innecesario y además, es propenso a errores. Para más información, mirar este hilo.

Aquí dejó una versión sin el uso de variables globales:

#include <iostream>
using namespace std;

/* La función retorna la matriz A rellenada con valores. */
int** pedirDatos(int&, int&);
void imprimirMatriz(int**, int, int);
/* La función retorna la matriz transpuesta de A. */
int** convertirTranspuesta(int**, int, int);
/* Para liberar la memoria de la matriz A y AT. */
void liberarMatriz(int**, int);

int main()
{
    int nFilas, nColumnas;
    int** p, **transpuesta;
    p = pedirDatos(nFilas, nColumnas);
    cout<<endl;
    imprimirMatriz(p, nFilas, nColumnas);
    cout<<endl;
    printf("%d, %d\n", nFilas, nColumnas);
    transpuesta = convertirTranspuesta(p, nFilas, nColumnas);
    cout<<endl;
    imprimirMatriz(transpuesta, nColumnas, nFilas);
    
    liberarMatriz(transpuesta, nColumnas);
    liberarMatriz(p, nFilas);
    return 0;
}

int** pedirDatos(int& nFilas, int& nColumnas)
{
    int** p;
    cout<<"Ingrese el numero de filas: "; cin>>nFilas;
    cout<<"Ingrese el numero de columnas: "; cin>>nColumnas;
    p = new int*[nFilas];
    for(int i=0;i<nFilas;i++)
        p[i] = new int[nColumnas];

    for(int i=0;i<nFilas;i++)
    {
        for(int j=0;j<nColumnas;j++)
        {
            cout<<"Ingrese un numero para la posicion ["<<i<<"]["<<j<<"]: ";
            cin>> p[i][j];
        }
        cout<<endl;
    }
    return p;
}

void imprimirMatriz(int** matriz, int nF, int nC)
{
    for(int i=0;i<nF;i++)
    {
        for(int j=0;j<nC;j++)
            cout<< matriz[i][j] <<" ";
        cout<<endl;
    }
}

int** convertirTranspuesta(int** matriz, int nF, int nC)
{
    int** transpuesta = new int*[nC];
    for(int i=0;i<nC;i++)
        transpuesta[i] = new int[nF];
    for(int i=0;i<nC;i++)
    {
        for(int j=0;j<nF;j++)
            transpuesta[i][j] = matriz[j][i];
    }
    return transpuesta;
}

void liberarMatriz(int** matriz, int nFilas)
{
    for(int i = 0; i != nFilas; ++i)
        delete[] matriz[i];
    delete[] matriz;
}

Esta versión es más reutilizable (se reutiliza código), ya que la función pedirDatos me sirve para llenar más de una matriz. En cambio, si hubiese usado las variables globales, limito a la función, ya que solo servirá para X matriz.

Observación #2

No uses el namespace std, mirar este hilo para más información.

MrDave1999
  • 7,491
  • 1
  • 7
  • 22