unerklärlich -> segfault wegen zu wenig speicher ?
-
Kann es sein, dass el zu weit läuft? Füg doch mal "&& (el != e_k_hat.end ())" zu den Abbruchbedingungen hinzu.
/edit Und was soll die Bedingung da? fabs(*i - 0.0) ist doch gleich fabs(*i)?!
-
danke für die Hilfe aber es ist wirklich immer so dass bei mir e_k_hat immer <= p_col ist. Das heißt er schießt nie darüber hinaus. Aber um sicherzugehen habe ich die abfrage auch reingemacht - das ergebnis war aber wie erwartet immer noch der segfault - es hat sich also nichts verändert.
Zum fasb. wenn ich einen float wert vergleichen will z.B a = 4.0 und ich will testen ob er == 0.0 ist dann geht dass so wegen der rechenungenauigkeit nicht....deswegen muss ich doch auf eine untere schranke gehen und mit dem absolutbetrag testen....ein blosses fasb(*i) bringt mir so also net was....
Danke
-
Und was glaubst du was bei einem - 0.0 passiert? Richtig es wird 0 abgezogen und evt. noch ein bischen ganz weit hinterm Komma, falls der double auf deiner Plattform zu ungenau ist.
-
Also in meiner Welt ist 4.0 - 0.0 immernoch 4.0 und nicht kleiner-gleich ist größer (-> fabs(*i) > epsilon entspricht deiner Zeile)... ist aber nicht so wichtig, daran sollte es nicht liegen.
/edit: mkay, zu spät.
Welchen Compiler und Debugger benutzt du?
-
hmm...jetzt bin ich ein wenig verwirrt...
folgendes:
float a = 1.0
if (a == 1.0)
...geht das so?
folgendes aus einem anderen thread:Gleitpunktzahl Vergleiche macht man immer mit
|WertA - WertB| < e
Das liegt daran das Gleitpunktzahlen eben recht ungenau werden, je größer der Bertrag vom Exponenten wird.deswegen dachte ich auch dass das bei a = 0.0 so sein müsste...
ich lasse mich gern belehren...
hmm aber mein hauptproblem löst das ja nicht

compiler: g++ 3.3.5
debugger: valgrind
-
Es geht eigentlich um das fabs( 4.0 - 0.0 ) < epsilon und nicht um ein 4.0 == 4.0
Das 0.0 in fabs kannst du weglassen nicht den epsilon-test.
-
hehe ach so ja logisch...hab vor lauter bäumen den wald nimmer gesehen...danke
-
ich habe nun vergeblich versucht mein programm abzuändern...mittlerweile weiß ich einfach nicht weiter....ich habe nun ALLE referenzen aufgelöst und übergebe funktionsargumente nur noch so damit lokale kopien angelegt werden...es hat nichts gebracht...
mittlerweile bekomme ich folgende meldung mit der ich nichts anfangen kann:
Conditional jump or move depends on uninitialised value(s) ==7212== at 0x1CE65746: std::__default_alloc_template<true, 0>::deallocate(void*, unsigned) (in /usr/lib/libstdc++.so.5.0.7) ==7212== by 0x8064E3A: Spai::ttt() (Spai.cpp:280) ==7212== by 0x806B3E9: Caching::Caching() (Caching.cpp:12) ==7212== by 0x80507BB: UIMainWindow::UIMainWindow() (UIMainWindow.cpp:25) ==7212== by 0x8050480: main (UIMain.cpp:16) ==7212== ==7212== Conditional jump or move depends on uninitialised value(s) ==7212== at 0x1B906C5D: operator delete(void*) (vg_replace_malloc.c:155) ==7212== by 0x1CE6575B: std::__default_alloc_template<true, 0>::deallocate(void*, unsigned) (in /usr/lib/libstdc++.so.5.0.7) ==7212== by 0x8064E3A: Spai::ttt() (Spai.cpp:280) ==7212== by 0x806B3E9: Caching::Caching() (Caching.cpp:12) ==7212== by 0x80507BB: UIMainWindow::UIMainWindow() (UIMainWindow.cpp:25) ==7212== by 0x8050480: main (UIMain.cpp:16) ==7212== ==7212== Invalid free() / delete / delete[] ==7212== at 0x1B906CA8: operator delete(void*) (vg_replace_malloc.c:155) ==7212== by 0x1CE6575B: std::__default_alloc_template<true, 0>::deallocate(void*, unsigned) (in /usr/lib/libstdc++.so.5.0.7) ==7212== by 0x8064E3A: Spai::ttt() (Spai.cpp:280) ==7212== by 0x806B3E9: Caching::Caching() (Caching.cpp:12) ==7212== by 0x80507BB: UIMainWindow::UIMainWindow() (UIMainWindow.cpp:25) ==7212== by 0x8050480: main (UIMain.cpp:16) ==7212== Address 0x1CE9C440 is not stack'd, malloc'd or (recently) free'dnach 5 tagen würde ich am liebsten den rechner zertrümmern

-
da ich nicht mehr weiterweiss post ich mal (dummerweise) die klasse in der der fehler liegen muss...kompilieren werdet ihr es net können weil ich fortran aufrufe drin hab....aber hier mal der teil der dafür verantwortlich sein muss - vielleicht hat jemand ein so geschultes auge dass er den fehler so erkennt...???
std::vector< double > Spai::Spai_Algorithm(const std::vector< double >& A, const std::vector< double >& P, const int dimension ) { int m, n, lda, k, info, lwork, one = 1; char *SIDE="L", *TRANS="T", //from left and transpose *UPLO="U", *NCHAR="N"; // upper triangular matrix not transposed std::vector< double > work, tau, M, A_hat, e_k_hat, p_col(dimension); std::vector< double >::iterator iter; for(int col = 0; col < dimension; col++) { Get_Pattern_Column (p_col, P, col, dimension); Create_e_k (col, dimension, e_k_hat); Create_A_Hat__e_k_Hat (A, n, m, p_col, A_hat, e_k_hat); Update_Lapack_Values (m, n, k, lda, tau, lwork, work); get_opt_lwork (A_hat, m, n); dgeqrf_ (&m, &n, &A_hat[0], &lda, &tau[0], &work[0], &lwork, &info); //Computing : Q^T * e_k_hat dormqr_ (SIDE, TRANS, &m, &n, &k, &A_hat[0], &lda, &tau[0], &e_k_hat[0], &lda, &work[0], &lwork, &info); Ectract_quadratic_content (A_hat, m, n); dtrtrs_ (UPLO, NCHAR, NCHAR, &n, &one, &A_hat[0], &n, &e_k_hat[0], &n, &info); Insert_m_k_hat (M, p_col, e_k_hat); } return M; } void Spai::Get_Pattern_Column(std::vector< double >& p_col, const std::vector< double >& P, const int col, const int dimension) { p_col.clear(); p_col.insert(p_col.begin(), P.begin() + dimension * col, P.begin() + dimension * ( col + 1 )); } void Spai::Create_e_k(const int col, const int dimension, std::vector< double >& e_k_hat) { e_k_hat.clear(); e_k_hat.resize(dimension, 0.0); e_k_hat[col] = 1.0; } void Spai::Create_A_Hat__e_k_Hat(const std::vector< double >& A, int& A_hat_dim_x, int& A_hat_dim_y, const std::vector< double >& p_col, std::vector< double >& A_hat, std::vector< double >& e_k_hat) { A_hat_dim_x = 0; A_hat_dim_y = p_col.size(); A_hat.clear(); for(int y = 0; y < p_col.size(); y++) { if(fabs(p_col[y] - 1.0) <= epsilon) { A_hat.insert(A_hat.end(), A.begin() + p_col.size() * y, A.begin() + p_col.size() * (y + 1)); A_hat_dim_x++; } } Erase_Zero_Rows(A_hat, A_hat_dim_x, A_hat_dim_y, e_k_hat); } void Spai::Erase_Zero_Rows(std::vector< double >& matrix, int& x_dim, int& y_dim, std::vector< double >& vector) { std::vector< bool > mask( y_dim ); for ( int y = 0; y < y_dim; ++y ) { mask[ y ] = true; if(fabs(vector[ y ] - 1.0) <= epsilon) mask[ y ] = false; for ( int x = 0; x < x_dim; ++x ) { if ( matrix[ x * y_dim + y ] != 0 ) { mask[ y ] = false; break; } } } matrix.erase( std::remove_if( matrix.begin(), matrix.end(), IS_MASKED( matrix, mask ) ), matrix.end() ); vector.erase( std::remove_if( vector.begin(), vector.end(), IS_MASKED( vector, mask ) ), vector.end() ); y_dim = matrix.size() / x_dim; } void Spai::Update_Lapack_Values(const int m, const int n, int& k, int& lda, std::vector< double >& tau, int& lwork, std::vector< double >& work) { tau.clear(); work.clear(); k = std::min(m,n); lda = std::max(m,1); lwork = std::max(n,1); tau.resize(k); work.resize(std::max(1,lwork)); } void Spai::Insert_m_k_hat(std::vector< double >& M, const std::vector< double >& p_col, const std::vector< double >& e_k_hat) { std::vector< double >::const_iterator el = e_k_hat.begin(); for( std::vector< double >::const_iterator i = p_col.begin(); i != p_col.end(); ++i ) { if( !(fabs(*i - 0.0) <= epsilon) ) M.push_back(*el++); else M.push_back(0.0); } } void Spai::Ectract_quadratic_content(std::vector< double >& A_hat, const int m, const int n) { if (m <= n) A_hat.erase(A_hat.begin() + m * m, A_hat.end()); else { std::vector< bool > mask( m ); for ( int y = 0; y < m; ++y ) { mask[ y ] = false; if(y >= n) mask[ y ] = true; } A_hat.erase( std::remove_if( A_hat.begin(), A_hat.end(), IS_MASKED( A_hat, mask ) ), A_hat.end() ); } } int Spai::get_opt_lwork(std::vector< double >& A_hat, int m, int n) { int lw = -1, info = 0, lwork = 0; double work = 0.0; std::vector< double > tau; dgeqrf_(&m, &n, &A_hat[0], &m, &tau[0], &work, &lw, &info); lwork = static_cast< int > (work); return lwork; }
-
Ich kann mit der Meldung auch nichts anfangen (ich benutze gdb). Kompilier mal mit der Flag -g2 und mach dann mit gdb einen backtrace ("gdb dein_program" -> run -> bt), dann sollte genau die Zeile gezeigt werden, bei der der Segfault fliegt.
-
danke für die hilfe filmor...
nach deinen anweisungen hier die meldung:
Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 1101404608 (LWP 8201)] 0x4155b642 in std::__default_alloc_template<true, 0>::allocate () from /usr/lib/libstdc++.so.5 (gdb) bt #0 0x4155b642 in std::__default_alloc_template<true, 0>::allocate () from /usr/lib/libstdc++.so.5 #1 0x080698aa in std::vector<double, std::allocator<double> >::_M_insert_aux (this=0xbffff3b0, __x=@0x814a6f0) at stl_alloc.h:232 #2 0x080669cf in Spai::Create_A_Hat_test (this=0xbffff610, A= {<std::_Vector_base<double, std::allocator<double> >> = {<std::_Vector_alloc_base<double, std::allocator<double>, true>> = {_M_start = 0x814a6e0, _M_finish = 0x814a760, _M_end_of_storage = 0x814a760}, <No data fields>}, <No data fields>}, A_hat_dim_x=@0xbffff31c, A_hat_dim_y=@0x8cf3e715, p_col= {<std::_Vector_base<double, std::allocator<double> >> = {<std::_Vector_alloc_base<double, std::allocator<double>, true>> = {_M_start = 0x814a140, _M_finish = 0x814a160, _M_end_of_storage = 0x814a160}, <No data fields>}, <No data fields>}) at stl_vector.h:371 #3 0x08065506 in Spai::Spai_Algorithm (this=0xbffff610, A=@0xbffff5d0, P=@0xbffff5b0, dimension=4) at stl_alloc.h:242 #4 0x08064b60 in Spai::ttt (this=0x0) at Spai.cpp:259 #5 0x0806adea in Caching (this=0xbffff640) at Caching.cpp:12 #6 0x080507bc in UIMainWindow (this=0xbffff690) at UIMainWindow.cpp:25 #7 0x08050481 in main (argc=1, argv=0x0) at UIMain.cpp:16ich habe ein wenig rumgespielt und die methode create_A_hat_test aus verzweiflung so (unvorteilhaft) umgeschrieben..sollte aber dasselbe tun...zumindest verstehe ich den fehler net...:
std::vector<double> Spai::Create_A_Hat_test(const std::vector< double > A, int& A_hat_dim_x, int& A_hat_dim_y, const std::vector< double > p_col, std::vector< double > e_k_hat2) { A_hat_dim_x = 0; A_hat_dim_y = p_col.size(); std::vector<double> erg; for(int y = 0; y < p_col.size(); y++) { if(fabs(p_col[y] - 1.0) <= epsilon) { for(int i = p_col.size() * y; i < (p_col.size() * (y + 1)); i++) { if(i >= A.size()) continue; erg.push_back(A[i]); } A_hat_dim_x++; } } return erg; }danke für hilfe...
-
hmm seltsam...wenn ich die methode so schreibe läuft er durch...also wenn ich vorher den vektor komplett in seiner grösse alloziiere und erst im nachheinein füllle....also so gehts:
std::vector<double> Spai::Create_A_Hat_test(const std::vector< double > A, int& A_hat_dim_x, int& A_hat_dim_y, const std::vector< double > p_col, std::vector< double > e_k_hat2) { A_hat_dim_x = 0; A_hat_dim_y = p_col.size(); int cnt = 0; for(int i = 0; i < p_col.size(); i++) if(fabs(p_col[i] - 1.0) <= epsilon) cnt++; std::vector<double> erg(cnt * p_col.size()); // std::vector<double> erg; int j = 0; for(int y = 0; y < p_col.size(); y++) { if(fabs(p_col[y] - 1.0) <= epsilon) { for(int i = p_col.size() * y; i < (p_col.size() * (y + 1)); i++) { if(i >= A.size()) continue; erg.push_back(A[i]); } A_hat_dim_x++; } } return erg; }aber warum geht das so nicht? Sollte doch klappen wegen dynamischer datenstruktur ???
std::vector<double> Spai::Create_A_Hat_test(const std::vector< double > A, int& A_hat_dim_x, int& A_hat_dim_y, const std::vector< double > p_col, std::vector< double > e_k_hat2) { A_hat_dim_x = 0; A_hat_dim_y = p_col.size(); // int cnt = 0; // for(int i = 0; i < p_col.size(); i++) // if(fabs(p_col[i] - 1.0) <= epsilon) // cnt++; // std::vector<double> erg(cnt * p_col.size()); std::vector<double> erg; int j = 0; for(int y = 0; y < p_col.size(); y++) { if(fabs(p_col[y] - 1.0) <= epsilon) { for(int i = p_col.size() * y; i < (p_col.size() * (y + 1)); i++) { if(i >= A.size()) continue; erg.push_back(A[i]); } A_hat_dim_x++; } } return erg; }
-
der fehler scheint merkwürdigerweise in der funktion
Create_e_k() zu liegen....wenn ich statt dieser methode folgende methode implementiere:
e_k_hat = Create_e_k_test(col, dimension); ... std::vector<double> Class::Create_e_k_test(const int col, const int dimension) { std::vector< double > erg(dimension, 0.0); erg[col] = 1.0; return erg; }also mit rückgabewert vector dann läuft alles prima durch....???
ABER WARUM???Kann es sein dass das irgendwie nur eine adresse hier überschrieben wird in der funktion und die dann den segfault einleitet oder irgendwas und damit die funktion Create_e_k() gar nicht der fehler ist????
ein backtrace und gdb ergibt folgendes bei der segfault methode:
#0 0x4155b642 in std::__default_alloc_template<true, 0>::allocate () from /usr/lib/libstdc++.so.5 #1 0x08066291 in Spai::Create_e_k (this=0xbffff610, e_k_hat=@0xbffff3f0, col=0, dimension=4) at stl_alloc.h:232 #2 0x08065de5 in Spai::Spai_Algorithm (this=0xbffff610, A=@0xbffff5d0, P=@0xbffff5b0, dimension=4) at Spai.cpp:312 #3 0x08065638 in Spai (this=0xbffff610) at Spai.cpp:246 #4 0x08068f9a in Caching (this=0xbffff640) at Caching.cpp:12 #5 0x080507bc in UIMainWindow (this=0xbffff690) at UIMainWindow.cpp:25 #6 0x08050481 in main (argc=1, argv=0x0) at UIMain.cpp:16
-
BUG GEFUNDEN:
es ist soweit diesen *!@% thread zu schließen...peinlich wiedermal aber mir ist jetzt alles wurscht...auf das sich alle lustig machen...(die frage ist nur wie man 5 tage 100 mal drüberlesen kann)...mal schaun obs jemand wenn ich die stelle hergeb auch findet
bestimmt...std::vector< double > e_k_hat; for(int col = 0; col < dimension; col++) { ... Create_e_k(e_k_hat, col, dimension); ... } ... void Spai::Create_e_k(std::vector< double >& e_k_hat, const int col, const int dimension) { std::vector<double> res(dimension, 0.0); res[col] = 1.0; e_k_hat.swap(res); }bitte tötet mich wenn ich jetzt schwachsinn laber aber ich denke da ich e_k_hat ohne dimension definiere und dann eine referenz in der methode übergebe muss er ins leere greifen oder nicht? Das seltsame war nur dass er eigentlich korrekt gearbeitet hat bis er irgendwann einfach in irgendwelchen schleifen stecken blieb....
und so läufts jetzt:
std::vector< double > e_k_hat(dimension);An dieser stelle danke an alle die sich zeit genommen haben zu posten...
-
lolz schrieb:
Es geht eigentlich um das fabs( 4.0 - 0.0 ) < epsilon und nicht um ein 4.0 == 4.0
Das 0.0 in fabs kannst du weglassen nicht den epsilon-test.Nochmal zu dem fabs().
Du hast schon recht *i == 4.0 geht nicht. Du musst ein Delta bilden.fabs(*i - 4.0) >= deltaso wirds gemacht. Delta ist dabei 0.000000000000000000001 oder sowas, jenach dem wie genau du es nehmen willst.
-
Mati schrieb:
BUG GEFUNDEN:
......std::vector< double > e_k_hat(dimension);...
irgendwie kommt mir das Thema (und der Variablenname) so bekannt vor.... aufch die Erklärung, "e_k_hat ist immer groß genug".
Gab's da nicht mal einen Thread (finde gerade nichts Derartiges), in dem Du gesagt hast, auch mit Größenüberprüfung von e_k_hat träte der Fehler auf.
Was mich mal interessiert: Hast Du wirklich gegen e_k_hat.size() oder e_k_hat.end() getestet ?Eigentlich hätte der Dir das richtige liefern sollen.
Ich bin mir bei der ganzen "Vorfüllungstrickserei" nie wirklich sicher , ob das so klappt, wie ich mir das denke - deswegen erlaube ich mir (gerade bei vektoren, die nur einmal geschrieben werden) immer den Luxus, sie per push_back() zu füllen.
"Da weiß man, was man hat, guten Abend"
Wäre vllt. auch was für Dich... ?!?Gruß,
Simon2.