[C++] Errore "core dumped"
Salve. Oggi provando a fare un esercizio sul creare una "calcolatrice" per operazioni con vettori e matrici, ho creato un programma che parte, e inoltre funziona per tutte le operazioni con vettori, mentre quando costruisco le matrici con una funzione che ho chiamato "cmat", mi esce l'errore "core dumped" e in quindi in teoria ci dovrebbe essere qualche problema per quanto riguarda i puntatori alle matrici (ci tengo a precisare che dal punto di vista teorico ancora non l'ho studiato). Se non vi reca disturbo, potreste dirmi dov'è l'errore?
p.s: so che ci sono parti inutili, ma prima di "raffinarlo", vorrei che funzionasse.
Edit: anche il comando del prodotto di uno scalare per un vettore dà lo stesso problema.
#include <iostream> using namespace std; int M,N,O; float SP(float* a,float*b,int I ){ float s; s=0; for(int i=0;i<I;i++){ s=s+a[i]*b[i]; } return s; } float* svec(float* a,float* b, int I) { float* c=new float [I]; for(int i=0;i<I; i++){ c[i]=a[i]+b[i]; } return c; } float* pvecs(float k, float* b, int I){ float* a; for(int i=0;i<I;i++){ a[i]=k*b[i]; } return a; } float** smat(float** A, float** B,int M, int N){ float** C=new float* [N]; for(int i=0;i<M;i++){ for(int j=0;j<N;j++){ C[i][j]=A[i][j]+B[i][j]; } } return C; } float* cvec(int I){ float* a=new float [I]; for(int i=0;i<I;i++){ cout<<"Inserire la componente "<<i+1<<" del vettore "<<endl; cin>>a[i]; } return a; } float** cmat(int I, int R){ float** A=new float* [R]; for(int i=0;i<I;i++){ for(int j=0;j<R;j++){ cout<<"Inserire la componente "<<i+1<<","<<j+1<<" della matrice"<<endl; cin>>A[i][j]; } } return A; } float** pmat(float** A, float** B, int M,int O){ float** C; for(int i=0;i<M;i++){ for(int j=0;j<O;j++){ for(int k=0;k<M;k++){ C[i][j]=C[i][j]+A[i][k]*B[k][j]; } } } return C; } void sym(float** A, int M){ int a=1; for(int i=0;i<M;i++){ for(int j=0;j<M;j++){ if(A[i][j]=A[j][i]){ a=a*1; } else{ a=a*0; } } } if(a=1){ cout<<"La matrice "<<char(138)<<" simmetrica e dunque diagonalizzabile per il Teorema Spettrale"<<endl; } else{ cout<<"La matrice non "<<char(138)<<" simmetrica e dunque per vedere se "<<char (138)<<" diagonalizzabile, servono altri test"<<endl; } } void trs(float** A, int M){ int a=1; for(int i=0;i<M;i++){ for(int j=0;j>=i;j++){ if(A[i][j]!=0){ a=a*1; } else{ a=a*0; } } } if(a=1){ cout<<"La matrice "<<char(138)<<" triangolare alta"<<endl; } else{ cout<<"La matrice non "<<char(138)<<" triangolare alta"<<endl; } } void tri(float** A,int M){ int a=1; for(int i=0;i<M;i++){ for(int j=0;j>i;j++){ if(A[i][j]=0){ a=a*1; } else{ a=a*0; } } } if(a=1){ cout<<"La matrice "<<char(138)<<" triangolare bassa"<<endl; } else{ cout<<"La matrice non "<<char(138)<<" triangolare bassa"<<endl; } } void diag(float** A,int M){ int a=1; for(int i=0;i<M;i++){ for(int j=0;j<M;j++){ if(i!=j){ if(A[i][j]=0){ a=a*1; } else{ a=a*0; } }else{ } } } if(a=1){ cout<<"La matrice "<<char(138)<<" diagonale"<<endl; } else{ cout<<"La matrice non "<<char(138)<<" diagonale"<<endl; } } int main(){ int z; do{ int a; do{ cout<<"Si scelga cosa fare inserendo il numero corrispondente all'istruzione"<<endl; cout<<"0 Somma tra vettori"<<endl; cout<<"1 Prodotto scalare tra vettori"<<endl; cout<<"2 Prodotto di uno scalare per un vettore"<<endl; cout<<"3 Somma tra matrici"<<endl; cout<<"4 Prodotto tra matrici"<<endl; cout<<"5 Controllare se una matrice "<<char(138)<<" simmetrizzabile"<<endl; cout<<"6 Controllare se una matrice "<<char (138)<<" triangolare superiore"<<endl; cout<<"7 Controllare se una matrice "<<char(138)<<" triangolare inferiore"<<endl; cout<<"8 Controllare se una matrice "<<char(138)<<" diagonale"<<endl; cin>>a; }while(a<0||a>8); switch(a){ case 0:{ int I; float* c; cout<<"Inserire la dimensione dei vettori"<<endl; cin>>I; float* d=cvec(I); float* b=cvec(I); c=svec(d,b,I); cout<<"Il vettore somma "<<char(138)<<" :"<<endl; cout<<"("; for(int i=0;i<I;i++){ cout<<c[i]<<" "; } cout<<")"; delete[] d; delete [] b; delete[] c; } break; case 1:{ int I; float c; cout<<"Inserire la dimensione dei vettori"<<endl; cin>>I; float* d=cvec(I); float* b=cvec(I); c=SP(d,b,I); cout<<"Il prodotto scalare "<<char(138)<<" "<<c<<endl; delete [] d; delete [] b; } break; case 2:{ int I; float* c; cout<<"Inserire la dimensione dei vettori"<<endl; cin>>I; float d; cout<<"Inserire lo scalare"<<endl; cin>>d; float* b=cvec(I); c=pvecs(d,b,I); cout<<"Il vettore moltiplicato "<<char(138)<<" :"<<endl; cout<<"("; for(int i=0;i<I;i++){ cout<<c[i]<<" "; } cout<<")"; } break; case 3:{ int I,J; float** c; cout<<"Inserire il numero di righe"<<endl; cin>>I; cout<<"Inserire il numero di colonne"<<endl; cin>>J; float** d=cmat(I,J); float** b=cmat(I,J); c=smat(d,b,I,J); cout<<"La matrice somma "<<char(138)<<" :"<<endl; cout<<"("; for(int i=0;i<I;i++){ for(int j=0;j<J;j++){ cout<<c[i][j]<<endl; } } } break; case 4:{ int I,J,K; float** c; cout<<"Inserire il numero di righe della prima matrice"<<endl; cin>>I; cout<<"Inserire il numero di righe della seconda matrice e il numero di colonne della prima"<<endl; cin>>J; cout<<"Inserire il numero di colonne della seconda matrice"<<endl; cin>>K; float** d=cmat(I,J); float** b=cmat(J,K); c=pmat(d,b,I,K); cout<<"La matrice prodotto "<<char(138)<<" :"<<endl; cout<<"("; for(int i=0;i<I;i++){ for(int j=0;j<K;j++){ cout<<c[i][j]<<endl; } } } case 5:{ float** b; int I; cout<<"Inserire l' ordine della matrice"<<endl; cin>>I; b=cmat(I,I); sym(b,I); } break; case 6:{ float** b; int I; cout<<"Inserire l'ordine della matrice"<<endl; cin>>I; b=cmat(I,I); trs(b,I); } break; case 7:{ float** b; int I; cout<<"Inserire l'ordine della matrice"<<endl; cin>>I; b=cmat(I,I); tri(b,I); } break; case 8:{ float** b; int I; cout<<"Inserire l'ordine della matrice"<<endl; cin>>I; b=cmat(I,I); diag(b,I); } break; } cout<<"Si vuole scegliere qualche altra cosa da fare? Se sì, inserire 1, altrimenti 0"<<endl; cin>>z; }while(z!=0); }
p.s: so che ci sono parti inutili, ma prima di "raffinarlo", vorrei che funzionasse.
Edit: anche il comando del prodotto di uno scalare per un vettore dà lo stesso problema.
Risposte
In [inline]pvecs[/inline], [inline]a[/inline] non è inizializzato. Dovresti scrivere [inline]float *a = new float;[/inline]
In [inline]smat[/inline], siccome vuoi \(\displaystyle M \) righe e \(\displaystyle N \) colonne, devi sostituire [inline]float **C = new float *[N];[/inline] con [inline]float **C = new float *[M];[/inline]. Inoltre manca la costruzione delle righe:
Stessa cosa in [inline]cmat[/inline].
In [inline]pmat[/inline], non solo manca totalmente la generazione di [inline]C[/inline] ma anche l'inizializzazione a \(\displaystyle 0 \) dei suoi elementi.
Non ho controllato tutto il resto, ma immagino che manchino molti delete. Tiene inoltre conto che quello non è l'unico modo in cui puoi costruire dinamicamente una matrice, ma per ora ti conviene correggere quello che hai già fatto.
In [inline]smat[/inline], siccome vuoi \(\displaystyle M \) righe e \(\displaystyle N \) colonne, devi sostituire [inline]float **C = new float *[N];[/inline] con [inline]float **C = new float *[M];[/inline]. Inoltre manca la costruzione delle righe:
float **smat(float **A, float **B, int M, int N) { float **C = new float *[M]; for (int i = 0; i < M; i++) { C[i] = new float[N]; for (int j = 0; j < N; j++) { C[i][j] = A[i][j] + B[i][j]; } } return C; }
Stessa cosa in [inline]cmat[/inline].
In [inline]pmat[/inline], non solo manca totalmente la generazione di [inline]C[/inline] ma anche l'inizializzazione a \(\displaystyle 0 \) dei suoi elementi.
Non ho controllato tutto il resto, ma immagino che manchino molti delete. Tiene inoltre conto che quello non è l'unico modo in cui puoi costruire dinamicamente una matrice, ma per ora ti conviene correggere quello che hai già fatto.
Grazie, non riuscivo proprio a capire l'errore.
Grazie di nuovo. Seguendo i tuoi consigli il programma sembra funzionare tranne per quanto riguarda alcuni valori (forse per la mancanza dei "delete" che devo capire bene come mettere perchè lo so fare solo per vettori, non so se per le matrici si deve fare qualcosa di particolare), e per quanto riguarda le funzioni di tipo void che stranamente mi danno lo stesso valore sia che la matrice soddisfa la condizione sia che non la soddisfa. Se non ti dispiace, quando e se hai tempo e se non ti reca disturbo, potresti spiegarmi dove sbaglio?
Edit 1: ho provato con alcune cose, ma il prodotto tra matrici da ancora problemi
Edit 1: ho provato con alcune cose, ma il prodotto tra matrici da ancora problemi
Ora sono con il cellulare, comunque l’errore è in
Hai frainteso il mio commento.
Intendevo dire che devi creare il vettore di dimensione N e poi mettere a 0 ogni C[j] di quella riga
C[i]=new float [O];
Hai frainteso il mio commento.
Intendevo dire che devi creare il vettore di dimensione N e poi mettere a 0 ogni C[j] di quella riga
Grazie per aver risposto, tuttavia non capisco, quello non è 0, ma è la lettera O.
ok, ma manca comunque l'inizializzazione a 0.
Ok, grazie. Quindi vanno tutti inizializzati? Se sì, per inizializzare un vettore o una matrice, come dovrei scrivere precisamente?
Scusa le tante domande stupide
Scusa le tante domande stupide
Basta porlo a 0 prima di usarlo:
float** pmat(float** A, float** B, int M,int O){ float** C=new float* [M]; for(int i=0;i<M;i++){ C[i]=new float [O]; for(int j=0;j<O;j++){ C[i][j] = 0; for(int k=0;k<M;k++){ C[i][j]=C[i][j]+A[i][k]*B[k][j]; } } } return C; }
Ah, ok, grazie di nuovo
Grazie ai tuoi consigli ora funziona praticamente tutto, tranne il prodotto di matrici per matrici rettangolari, per quelle quadrate infatti tutto è in regola
È normale che non funzioni: manca una dimensione in input. Comunque è generalmente meglio separare la funzione che fa il calcolo dall'allocazione della matrice. Per esempio:
Nota che ho aggiunto un test per la funzione. Comunque, spesso le matrici sono rappresentate come vettori singoli e non come vettori di vettori.
Comunque più che C++ sembra C con l'IO e allocazione del C++.
#include <iostream> #include <cmath> using namespace std; float** allocaMatrice( int numero_righe, int numero_colonne ) { float** matrice = new float*[ numero_righe ]; for ( int i = 0; i < numero_righe; i++ ) { matrice[ i ] = new float[ numero_colonne ]; } return matrice; } void deleteMatrice( float**& matrice, int numero_righe ) { if ( !matrice ) return; for ( int i = 0; i < numero_righe; i++ ) { if ( !matrice[ i ] ) { delete[] matrice[ i ]; matrice[ i ] = nullptr; } } delete[] matrice; matrice = nullptr; } void azzeraMatrice( float** matrice, int numero_righe, int numero_colonne ) { for ( int i = 0; i < numero_righe; ++i ) { for ( int j = 0; j < numero_colonne; ++j ) { matrice[ i ][ j ] = 0.0f; } } } // Calcola AxB = C // A e' una matrice MxP // B e' una matrice PxN // C e' una matrice is MxN. void prodottoMatrici( float** A, float** B, float** C, int M, int P, int N ) { azzeraMatrice( C, M, N ); // senza questa linea fa un fused multiply and add. for ( int i = 0; i < M; i++ ) { for ( int j = 0; j < N; j++ ) { for ( int k = 0; k < P; k++ ) { C[ i ][ j ] += A[ i ][ k ] * B[ k ][ j ]; } } } } // La tua funzione float** pmat( float** A, float** B, int M, int P, int N ) { float** C = allocaMatrice( M, N ); prodottoMatrici( A, B, C, M, P, N ); return C; } float check( float** A, float** B, int numero_righe, int numero_colonne ) { float error = 0.0f; for ( int i = 0; i < numero_righe; ++i ) { for ( int j = 0; j < numero_colonne; ++j ) { error += std::abs( A[ i ][ j ] - B[ i ][ j ] ); } } return error; } int main( ) { float A1[ 5 ] = {1, 2, 0, 0, 0}; float A2[ 5 ] = {0, 1, 2, 0, 0}; float A3[ 5 ] = {0, 0, 1, 3, 4}; float* A[ 3 ] = {A1, A2, A3}; float B1[ 4 ] = {1, 0, 0, 0}; float B2[ 4 ] = {2, 1, 0, 0}; float B3[ 4 ] = {3, 2, 1, 0}; float B4[ 4 ] = {0, 0, 0, 1}; float B5[ 4 ] = {6, 6, 6, 6}; float* B[ 5 ] = {B1, B2, B3, B4, B5}; // result float C1[ 4 ] = {5, 2, 0, 0}; float C2[ 4 ] = {8, 5, 2, 0}; float C3[ 4 ] = {27, 26, 25, 27}; float* C[ 3 ] = {C1, C2, C3}; float** res = pmat( A, B, 3, 5, 4 ); cout << "errore: " << check( C, res, 3, 4 ) << endl; deleteMatrice( res, 3 ); }
Nota che ho aggiunto un test per la funzione. Comunque, spesso le matrici sono rappresentate come vettori singoli e non come vettori di vettori.
Comunque più che C++ sembra C con l'IO e allocazione del C++.
Grazie veramente per tutto e scusa nuovamente il disturbo. Ora funziona tutto.