2016-11-30 5 views
1

Ich habe eine Klasse erstellt, die eine symmetrische Toeplitz-Matrix erstellen soll (see here). Die Implementierung der Klasse wird hierFalsche Prüfsumme für freigegebenes Objekt - Fehler beim Drucken

gezeigt
class toeplitz{ 
private: 
    int size; 
    double* matrix; 
public: 
    toeplitz(const double* array, const int dim){ 
     size = dim; 
     matrix = new double(size*size); 
     for(int i = 0; i < size; i++){ 
      for (int j = 0; j < size; j++){ 
       int index = std::abs(i - j); 
       matrix[i*size + j] = array[index]; 
      } 
     } 
    } 

    ~toeplitz(){ 
     delete[] matrix; 
    } 

    void print() const{ 
     //loop over rows 
     for (int i = 0; i < size; i++){ 
      //loop over colums 
      for (int j = 0; j < size; j++){ 
       double out = matrix[i*size + j]; 
       std::cout << std::setw(4) << out; 
      } 
     //start new line for each row 
     std::cout << "\n"; 
     } 
    } 

}; 

Ich kann nicht sehen, was mit diesem falsch ist, aber wenn ich versuche, und verwenden Sie diese in einer einfachen Testfunktion, ich malloc Fehler bekommen. Die Hauptfunktion die ich habe ist

int main(){ 
    double array[] = {0,1,1,2}; 
    int len = sizeof(array)/sizeof(array[0]); 
    std::cout<<"length of array " << len << std::endl; 
    toeplitz tp = toeplitz(array, len); 
    tp.print(); 
} 

Es kompiliert und ausgeführt, wenn ich die tp.print() Linie auslassen, aber wenn ich diese Zeile hinzufügen, ich Fehler bekommen

test_toeplitz(8747,0x7fffdbee63c0) malloc: *** error for object 0x7fb119402788: 
incorrect checksum for 
freed object - object was probably modified after being freed. 
*** set a breakpoint in malloc_error_break to debug 
Abort trap: 6 

Ich kann nicht erklären, warum das ist. Ich habe mir die anderen Fragen dazu hier angeschaut, aber ich kann nicht sagen, wie sie sich auf das beziehen, was ich getan habe. Wie ich es verstehe, hat es damit zu tun, Speicher entweder doppelt freizugeben oder zu versuchen, den Speicher zu ändern, nachdem er freigegeben wurde, aber ich kann nicht sehen, wo mein Code das tut. Jeder Einblick in das, was vor sich geht, würde geschätzt werden.

+0

sollte ich hinzufügen , sehr gelegentlich läuft es tatsächlich in Ordnung, und manchmal gibt es auch den Fehler "segmentation fault: 11" anstatt – bigbadpiano

+0

*** Objekt wurde wahrscheinlich nach dem Freigeben geändert. *** Ich würde das untersuchen. – drescherjm

+0

*** Ich sollte fügen Sie hinzu, sehr gelegentlich läuft es wirklich in Ordnung, und manchmal gibt es auch den Fehler "segmentation fault: 11" statt *** Dies ist ein klarer Hinweis auf Undefined Behavior. – drescherjm

Antwort

3

Sie stolperte auf der klassischen:

matrix = new double(size*size); 

die size*size einen doppelten Wert zuweist, wenn Sie tun wollte:

matrix = new double[size*size]; 

um ein Array der richtigen Größe zuzuordnen. Sie erhalten also undefiniertes Verhalten. Manchmal funktioniert es manchmal nicht abhängig von der Speicherkonfiguration.

Da Sie C++ verwenden, empfehle ich Ihnen std::vector<double> oder Eigen-Matrix-Vorlage verwenden, und für immer C-Arrays fallen (nicht mehr Speicherlecks, nicht mehr gescheiterte Zuweisungen möglich Grenzprüfung, nur Vorteile)

+0

Oder noch besser ein Vektor (ja ja, ich weiß, dass der Vektor die Größe nicht ändert, aber hey, es vermeidet manuelle Speicherverwaltung!) Und hätte wahrscheinlich eine Index-Ausnahmebegrenzung ausgelöst) – Borgleader

+0

Die Verwendung eines Vektors garantiert keine Grenzprüfung mit dem Operator '[]'. Sie müssen 'vector :: at' verwenden, um nach Grenzen zu suchen. Aber einverstanden (und redigierend meine Antwort, als Sie kommentierten) –

+0

Ja, ich weiß es ist keine Garantie, deshalb sagte ich wahrscheinlich. Ich denke, * VS 'Implementierung hat zu diesem Zweck YMMV behauptet. ;) (Mach dir keine Sorgen, du hast bereits mein Upboat) – Borgleader

Verwandte Themen