2017-04-21 4 views
0

Ich versuche, ein Array zu initialisieren, die ich in meiner Klasse Erklärung gemacht habe und ich weiß nicht, was ich falsch mache. Ich verstehe, dass, wenn Sie ein Array in eine Funktion übergeben, es in einen Zeiger auf das erste Zeichen zerfällt. Der Code bricht bei meiner zweiten strcpy() Zeile ab, aber ich bin mir nicht sicher, was ich falsch mache (ich habe sehr wenig Erfahrung mit strcpy()).Verwenden von übergebenen Array, um andere Array zu initialisieren

Mein Code lautet wie folgt:

class TestClass 
{ 
public: 
    TestClass(char []); 
    ~TestClass(); 
    void Append(TestClass); 

    char* m_string; 
}; 

TestClass::TestClass(char incstring[]) 
{ 
    char currentChar = 'a'; 
    int numOfChars = 0; 

    while (currentChar != '\0') { 
     currentChar = *(incstring + numOfChars); 
     numOfChars++; 
    } 

    char* tmp = new char[numOfChars-1]; 
    strcpy(tmp, incstring); 
    strcpy(m_string, tmp); 
} 

Mein int main() ist einfach:

int main(){ 
    TestClass* test = new TestClass("Hello"); 
} 

Wenn es erwähnenswert ist, ist numOfChars gleich 6 ist, wie es richtig sein sollte.

die Ausnahme ausgelöst wird: „Zugriffsverletzung Schreibort 0xCDCDCDCD.“

+2

'm_string' ist nie initialisiert. –

+1

Bitte benutzen Sie 'std :: string' und ersparen Sie sich den Ärger. Außerdem gibt es keinen Grund für 'new' in Ihrem' main': 'TestClass-Test (" Hello ");' würde genauso gut ohne das Speicherleck funktionieren. – aschepler

+0

Ich habe es nur auf nullptr initialisiert und bekomme die selbe Ausnahme. –

Antwort

1

Sie keine Speicher für m_string sind Zuteilung, bevor Sie Daten tmp-m_string kopieren. Deshalb stürzt du zusammen. m_string zeigt nicht auf eine gültige Speicheradresse.

Da Sie tmp bereits zugewiesen haben und es nicht mehr verwenden werden, können Sie einfach den tmp Zeiger direkt auf m_string zuweisen, ohne eine weitere Kopie auszuführen.

Beachten Sie auch, dass Ihre while Schleife Duplizieren ist, was strlen() bereits tut, also sollten Sie einfach strlen() verwenden.

Try this:

TestClass::TestClass(char incstring[]) 
    : m_string(new char[strlen(incstring)+1]) 
{ 
    strcpy(m_string, incstring); 
} 

TestClass::~TestClass() 
{ 
    delete[] m_string; 
} 

Welche vereinfacht werden kann strdup() statt (verwenden free() statt delete[] es ausplanen) mit:

TestClass::TestClass(char incstring[]) 
    : m_string(strdup(incstring)) 
{ 
} 

TestClass::~TestClass() 
{ 
    free(m_string); 
} 

Mit dieser sagte, Ihr main() undicht Speicher, wie Sie befreien nicht das test Objekt:

Oder einfach:

int main(){ 
    TestClass test("Hello"); 
} 

Und schließlich, stellen Sie sicher, dass Sie die Rule of Three in Ihrer Klasse implementieren. Sie verwalten dynamische Speicher, der in dem destructor befreit wird, so müssen Sie auch eine Kopie Konstruktor und eine Kopie Zuweisungsoperation, die Integrität von m_string zu gewährleisten, wenn TestClass Werte aus anderen TestClass Werten zu schaffen:

class TestClass 
{ 
private: 
    char* m_string; 

public: 
    TestClass(char *incstring = 0); 
    TestClass(const TestClass &src); 
    ~TestClass(); 

    void Append(const TestClass &str); 
    void Swap(TestClass &Other); 

    TestClass& operator=(const TestClass &lhs); 
}; 

TestClass::TestClass(char *incstring) 
    : m_string(0) 
{ 
    if (incstring) 
    { 
     m_string = new char[strlen(incstring)+1]; 
     strcpy(m_string, incstring); 
    } 
} 

TestClass::TestClass(const TestClass &src) 
    : m_string(0) 
{ 
    if (src.m_string) 
    { 
     m_string = new char[strlen(src.m_string)+1]; 
     strcpy(m_string, src.m_string); 
    } 
} 

TestClass::~TestClass() 
{ 
    delete[] m_string; 
} 

void TestClass::Append(const TestClass &str) 
{ 
    if (str.m_string) 
    { 
     TestClass tmp; 
     tmp.m_string = new char[strlen(m_string)+strlen(str.m_string)+1]; 
     strcpy(tmp.m_string, m_string); 
     strcat(tmp.m_string, str.m_string); 
     Swap(tmp); 
    } 
} 

void TestClass::Swap(TestClass &Other) 
{ 
    char *ptr = m_string; 
    m_string = Other.m_string; 
    Other.m_string = ptr; 
} 

TestClass& TestClass::operator=(const TestClass &lhs) 
{ 
    if (this != &lhs) { 
     TestClass(lhs).Swap(*this); 
    }  
    return *this; 
} 
Verwandte Themen