2017-04-30 2 views
0

Nach Referenzieren der folgenden Ressourcen: here und here. So kann ich sehen, wie der richtige Weg dazu ist. Dann nach dem Lesen Beitrag, kann ich sehen, dass meine vorherige Warnung wurde behoben, indem ein typechar von char* "mystring" in das Argument einer Funktion übergeben wird.C++ - Übergeben Char * durch Funktion Speicherfreigabe Fehler

Allerdings bekomme ich immer noch einen Fehler für eine ziemlich intuitive paar Zeilen Code (obwohl ich nicht C++ in irgendeiner Art berührt habe, daher, warum ich einige Probleme habe).

TextDocument.h

#ifndef ____TextDocument__ 
#define ____TextDocument__ 

#include <stdio.h> 

class TextDocument { 
    char *text; 
    char *docName; 
public: 
    void SetText(char *otherText); 
    char *GetText(); 
    void SetDocName(char *newName); 
    char *GetDocName(); 
    int GetTextLength(); 
}; 

#endif /* defined(____TextDocument__) */ 

TextDocument.cpp

#include <iostream> 
#include "TextDocument.h" 
#include "string.h" 
using namespace std; 

void TextDocument::SetText(char *otherText){ 

    cout << otherText << endl; 

    if (text != 0) 
     delete text;   //free the memory 

    text = new char[strlen(otherText)+1]; // +1 for the null char 
    strcpy(text, otherText);    //text <- otherText 
} 

char *TextDocument::GetText(){ 
    return text; 
} 

void TextDocument::SetDocName(char *name){ 

    if (docName != 0) 
     delete docName; 

    docName = new char[strlen(name) + 1]; // +1 for the \0 terminator 
    strcpy(docName, name);     // docName <- name 
} 

char *TextDocument::GetDocName(){ 

    return docName; 
} 

int TextDocument::GetTextLength(){ 
    if (text != 0) { 
     return strlen(text); 
    } 
    else return 0; 
} 

main.cpp

#include <iostream> 
#include "string.h" 
#include "TextDocument.h" 
#include "Folder.h" 

using namespace std; 

int main(void){ 

    TextDocument *sampleDoc; 
    sampleDoc = new TextDocument; 


    sampleDoc->SetText((char *)"some str"); // I have no idea why there is a linker error here. 

    return 0; 
} 

run.sh

g++ *.cpp -o main 
./main 

Ausgabe:

Blakes-MacBook-Pro:data_encapsulation bmc$ sh run.sh 
some str 
main(848,0x7fff7f54b300) malloc: *** error for object 0x8000000000000000: pointer being freed was not allocated 
*** set a breakpoint in malloc_error_break to debug 
run.sh: line 2: 848 Abort trap: 6   ./main 

Problem 1

Warum ist es nicht mein char * Text zu löschen, wenn es uncreated ist.

Problem 2 (Sidebar Problem, nicht die sofortige Ausgabe)

Wo ist der beste Platz für alle, die H-Dateien zu setzen? Beispiel) Ich brauche #include <iostream> und using namespace std innerhalb von ein paar verschiedenen .h oder .cpp Dateien, wo wäre der beste Ort, um sie zu setzen; Wenn Sie sie nur in den Hauptteil stellen, werden diese anderen Module nicht in der Lage sein, es zu sehen und Fehler zu ergeben.

1. Fix Submission

So, nachdem einige mehr mit dieser Sache Verschrauben, habe ich den Fehler mit zu gehen weg von der Linie von

Ändern
if (text != 0) 
    delete text;   //free the memory 

zu

if (text) 
    delete text;   //free the memory 

Ich denke, Ich verstehe die Logik if (thestringeisntempty) delete text; aber warum funktioniert if(text != 0) delete text; nicht auch?

+1

Ihr Problem verwendet nicht std :: string, sondern die sehr unrecommended new und löschen. –

+0

Setzen Sie im Konstruktor von TextDocument Text auf 'NULL' (oder' nullptr')? EDIT: vergiss, es gibt keinen Konstruktor. –

+0

@The Techel, so verwenden Sie einfach ein 'std :: string' Datenelement und dann nur seinen Wert dort zurückgesetzt? Ich versuche, Best Practices zu lernen. – bmc

Antwort

1

Zwei Lösungen:

  1. einen Konstruktor Textdocument hinzufügen, die Ihren Zeiger richtig initialisiert.

    TextDocument() : text(nullptr), docName(nullptr) {} 
    

Verwenden NULL statt nullptr, wenn Ihr Compiler die letztere nicht unterstützt.

  1. Entfernen Sie mit char * s und verwenden Sie std :: string.
+0

Das funktioniert, aber ich bin immer noch verwirrt, warum ich anfänglich 'char * text' oder' std :: string text' initialisieren muss. Ist es wie ein Block von nicht initialisiertem Speicher, sogar ohne den NULL-Zustand? – bmc

+0

Sie müssen das char * zu etwas Bekanntem initialisieren, damit Sie sicher behaupten können, dass es später ist. Hier bedeutet es, dass der Zeiger momentan nicht auf ein gültiges Zeichen zeigt. Übergeben Sie nullptr (= ungültiger Zeigerwert) nicht an den Konstruktor von std :: string und verwenden Sie den Standardkonstruktor. Dadurch wird das string-Objekt in einem 'leeren'-Zustand belassen. –