2016-08-04 18 views
1

Ich habe diesen Code:Verschiedene Ausgangs je löschen

#include <iostream> 
using namespace std; 
char* pass(char* p){ 
    char* a = new char[10]; 
    a[0] = 'S'; 
    a[1] = 'e'; 
    a[2] = 'r'; 
    a[3] = 'g'; 
    a[3] = 'e'; 
    a[3] = 'y'; 
    a[4] = '\0'; 
    p = a; 
    //delete [] a; 
    return p; 
} 
int main(int argc,char* argv[]){ 
    char* p1 = new char[1000]; 
    p1[0] = 'G'; 
    p1[1] = 'e'; 
    p1[2] = 'r'; 
    p1[3] = 'y'; 
    p1[4] = '\0'; 
    char* p2 = p1; 
    cout << p2 << endl; 
    cout << pass(p2) << endl; 
    delete [] p1; 
} 

und der Ausgang ist:

Gery 
Sery 

aber wenn ich die Linie delete [] a Kommentar- habe ich diese Ausgabe:

Gery 
ê§É 

Warum?

+2

'p = a löschen;' nicht die Werte kopieren, wie Sie vielleicht denken. – DimChtz

+3

Sie sollten wirklich auf Zeiger und Speicherverwaltung in C++ auffrischen. Es scheint, dass es zu viel ist, was du nicht verstehst, damit eine Antwort effektiv ist. –

+0

Und deshalb sollten Sie 'std :: stirng' verwenden und sich die Implementierung um die Zuweisung und das Kopieren kümmern. – NathanOliver

Antwort

2

In dieser Funktion

char* pass(char* p){ 
    char* a = new char[10]; 
    a[0] = 'S'; 
    a[1] = 'e'; 
    a[2] = 'r'; 
    a[3] = 'g'; 
    a[3] = 'e'; 
    a[3] = 'y'; 
    a[4] = '\0'; 
    p = a; 
    //delete [] a; 
    return p; 
} 

der Parameter ist eine lokale Variable der Funktion. Nach dem Beenden der Funktion wird es zerstört.

Sie können die Funktion und seine Forderung vorstellen, die

pass(p2); 

char* pass(/*char* p*/){ 
    char* p = p2; 
    char* a = new char[10]; 
    a[0] = 'S'; 
    a[1] = 'e'; 
    a[2] = 'r'; 
    a[3] = 'g'; 
    a[3] = 'e'; 
    a[3] = 'y'; 
    a[4] = '\0'; 
    p = a; 
    //delete [] a; 
    return p; 
} 

folgende Art und Weise, wie Sie den ursprünglichen Zeiger p2 sehen nicht in der Funktion geändert werden. Die Funktion ändert ihre lokale Variable , die als Parameter deklariert ist.

Wenn Sie die Löschanweisung auskommentieren, wird der Speicher, auf den der Rückgabewert verweist, gelöscht und der zurückgegebene Zeiger ist ungültig. aufgrund Aussage

cout << pass(p2) << endl; 

In diesem Fall hat das Programmverhalten nicht definiert, wo ein Versuch, es gibt die gelöschte Speicher mit dem Rückgabewert der Funktion zuzugreifen.

Es ist also nicht sinnvoll, Zeiger auf gelöschten Speicher zurückzugeben.

Was Sie tun möchten, können auf drei Arten

Die erste erreicht werden, den Parameter als Referenz

char* pass(char* &p){ 
      ^^^^^^^^ 
    char* a = new char[10]; 
    a[0] = 'S'; 
    a[1] = 'e'; 
    a[2] = 'r'; 
    a[3] = 'g'; 
    a[3] = 'e'; 
    a[3] = 'y'; 
    a[4] = '\0'; 
    p = a; 
    return p; 
} 

und rufen Sie die Funktion wie

cout << pass(p2) << endl; 

Die zweite erklären Eine besteht darin, den Parameter als Zeiger auf einen Zeiger zu deklarieren, der den ursprünglichen Zeiger indirekt akzeptiert

char* pass(char* *p){ 
      ^^^^^^^^ 
    char* a = new char[10]; 
    a[0] = 'S'; 
    a[1] = 'e'; 
    a[2] = 'r'; 
    a[3] = 'g'; 
    a[3] = 'e'; 
    a[3] = 'y'; 
    a[4] = '\0'; 
    *p = a; 
    ^^^^^^^^ 
    return *p; 
    ^^^^^^^^^^ 
} 

und rufen Sie die Funktion wie

cout << pass(&p2) << endl; 

Und endlich konnte man einfach den Rückgabewert auf den ursprünglichen Zeiger zuweisen. Zum Beispiel

char* pass(char* p){ 
    char* a = new char[10]; 
    a[0] = 'S'; 
    a[1] = 'e'; 
    a[2] = 'r'; 
    a[3] = 'g'; 
    a[3] = 'e'; 
    a[3] = 'y'; 
    a[4] = '\0'; 
    p = a; 
    return p; 
} 

und rufen die functionj wie

cout << (p2 = pass(p2)) << endl; 

obwohl in diesem Fall ist der Parameter obsolet.

In jedem Fall sollten Sie die zugewiesenen Speicher am Ende des Programms wie

delete [] p2; 
1
p = a 

kopiert die Werte nicht.

Was Sie suchen ist wahrscheinlich:

memcpy(p, a, 10*sizeof(char)); 
+2

Ich denke nicht, dass dies eine hilfreiche Antwort ist: Erstens, es ist nicht die C++ Art, Dinge zu tun. Und es erklärt nicht wirklich, was vor sich geht. Schließlich würden Sie selbst im Kontext von Low-Level-C++ keinen solchen Code schreiben (verwenden Sie stattdessen "std :: copy" oder fügen Sie zumindest die richtigen Header hinzu und entfernen Sie das nutzlose 'sizeof (char)'). –

+0

@KonradRudolph Ich agrre, weil der zurückgegebene Zeiger in jedem Fall auf gelöschten Speicher zeigt, wenn die Löschanweisung auskommentiert werden soll. –

0

Weil Ihre uncommented Linie gibt den Speicher Sie zurückgeschickt, und den Compiler, wahrscheinlich als Debug-Hilfe, überschrieb den freigegebenen Speicher.

Ihre ist nach Wert übergeben, so p = a; nicht tatsächlich ändern p1 innerhalb Haupt. Sie initialisieren im Wesentlichen Speicher, löschen ihn und geben dann einen Zeiger auf den gelöschten Speicher zurück.

Ohne das zusätzliche Löschen, verlieren Sie nur diesen Speicher.