2016-03-29 5 views
2

Ich arbeite an einem Problem und ich wurde gebeten, eine Funktion zu erstellen, die einen Zeiger zurückgibt. Das Programm, das ich geschrieben habe, funktioniert gut und alles; Ich erstelle jedoch dynamische Speicherzuweisung in meiner Funktion *newArray und ich glaube nicht, dass ich diesen zugewiesenen Speicher freigeben, der Zeiger ptr2 zeigt auf innerhalb dieser Funktion. Gibt es eine Möglichkeit, diese Erinnerung freizugeben?Wie kann ich dynamischen Speicher freigeben, der in einer Funktion zugewiesen ist?

Ich dachte darüber nach, der Funktion einen weiteren Parameter hinzuzufügen - den Zeiger ptr2 aus der Hauptfunktion - und ändere nur den Zeiger innerhalb der Funktion, aber das widerspricht dem Zweck der Funktion, die einen Zeiger zurückgibt. Irgendwelche Gedanken hier?

Hier ist mein Code:

//Problem #12 
#include <iostream> 
using namespace std; 

void SizeEntry(int*); 
void DataEntry(int*, int); 
void ShowArray(int *, int); 
int *newArray(int *, int); 

int main() 
{ 
    int size, new_size; 
    int *ptr=nullptr, *ptr2 = nullptr; 

    //grab size and dynamically allocate an array to the entered size 
    SizeEntry(&size); 
    ptr = new int[size]; 

    //make size of second array 
    new_size=size+1; 

    //Fill array with data and make a new copy w/ requirements 
    DataEntry(ptr, size); 
    ptr2 = newArray(ptr, size); 

    cout<<"\nHere is the first array: \n"; 
    ShowArray(ptr, size); 
    cout<<"Here is the new array: \n"; 
    ShowArray(ptr2, new_size); 

    //free allocated array 
    delete [] ptr; 
    delete [] ptr2; 
    ptr = nullptr; 
    ptr2 = nullptr; 

    return 0; 
} 
void SizeEntry(int *size) 
{ 
    cout<<"Enter the size of your list: "; 
    cin>>*size; 
    while(*size<0) 
    { 
     cout<<"Size must be non-negative, enter another number: "; 
     cin>>*size; 
    } 
} 
void DataEntry(int *ptr, int size) 
{ 
    for(int count = 0; count<size; count++) 
    { 
     cout<<"Enter data for entry #"<<(count+1)<<": "; 
     cin>>*(ptr+count); 
     while(*(ptr+count)<0) 
     { 
      cout<<"Data point cannot be negative, try again: "; 
      cin>>*(ptr + count); 
     } 
    } 
} 
void ShowArray(int *ptr, int size) 
{ 
    for(int count=0; count<size; count++) 
     cout<<*(ptr+count)<<" "; 
    cout<<endl; 
} 
int *newArray(int *ptr, int size) 
{ 
    int *ptr2=nullptr; 
    int new_size = size+1; 
    int counter=0; 

    ptr2 = new int[new_size]; 

    for(int count=0; count<new_size; count++) 
    { 
     if(count==0) 
      ptr2[count]=0; 
     else 
     { 
      ptr2[count]=ptr[counter]; 
      counter++; 
     } 
    }   
    return ptr2; 
} 
+3

Betrachten Sie Smartpointer –

+0

Sie geben diesen Speicher mit 'delete [] ptr2' frei, wenn Sie damit fertig sind. Sie können es vorher nicht freigeben. –

+0

Hallo Sami, das lösche [] ptr2 ist in main und gibt den Speicher frei, der in main erstellt wurde, auf den der ptr2 Zeiger zeigt, aber ich erschaffe auch einen anderen in * newArray Funktion. – Francisco

Antwort

0

Um den Speicher freizugeben, der von "new Operator" in C++ zugewiesen wurde, benutze einfach delete operator und sonst nichts.

Keine Notwendigkeit, dem Zeiger, dessen Speicher bereits vom Löschoperator freigegeben wurde, null zuzuweisen.

PS: WENN SIE DIESEN POINTER WIEDER VERWENDEN WOLLEN, NUR DANN ZU NULL ZUWEISEN.

In Ihrem Fall sind die letzten zwei Codezeilen nutzlos, wenn Sie diesen Zeiger nicht erneut verwenden möchten.

//free allocated array 
    delete [] ptr; 
    delete [] ptr2; 
    ptr = nullptr; //Useless as memory is already free assigned to ptr 
    ptr2 = nullptr;//Useless as memory is already free assigned to ptr2 

In der Funktion * newArray geben Sie einen Zeiger, d. H. Ptr2.

Wenn Sie ptr2 zurückgeben, wird eine Kopie des Werts (eine Adresse) von ptr2 erstellt und an den Aufrufer zurückgegeben. ptr2 wurde mit automatischer Speicherdauer deklariert. Es ist der Speicher, auf den es sich bezieht, der freigegeben werden muss und du machst es in main, da ptr2 von * newArray zu ptr2 der Hauptfunktion zugewiesen wird.

PS: Wenn Sie irgendwelche Zweifel haben, es in Visual Studio zu debuggen, werden Sie die klare Idee bekommen.

+0

So wird der Speicher, der in der newArray-Funktion zugewiesen wird, auch durch den Löschoperator freigegeben? – Francisco

+0

@Francisco: Ich habe meine Antwort geändert. hoffe, es wird die Idee klar – secretgenes

+0

Vielen Dank! Ich habe das anhand meines Lehrbuchs überprüft, da dort ein Beispiel verwendet wird, das eine Funktion verwendet, um ein dynamisches Speicherarray zu erstellen, es aufzufüllen und einen Zeiger auf das Array zurückgibt. Es erstellt auch ein anderes dynamisch zugeordnetes Array in der Hauptfunktion und ordnet es dem von der Funktion ausgegebenen Zeiger zu. Wenn Sie den Speicher in der Hauptfunktion freigeben, wendet das Beispiel den Löschoperator auf den in der Hauptfunktion erstellten Zeiger an. – Francisco

1

Sie ptr2 in Haupt sind zu befreien. Dazu weisen Sie prt2 Ihrer Funktion zuvor mit Ihrem Rückgabewert zu. Also zeigen beide Zeiger auf den gleichen Speicher wie dies der Gedanke von Zeigern ist. Wenn Sie ptr2 in main freigeben, geben Sie automatisch ptr2 in Ihrer Funktion frei, weil sie gleich sind -> sehen Sie Ihre Aufgabe. Aus meiner Sicht gibt es jetzt Probleme mit dem zugewiesenen Speicher.

+0

Ich glaube nicht, dass das korrekt ist. Aber ich könnte hier falsch liegen. Die Funktion newArray() führt einen neuen Befehl aus, der nicht auf den gleichen Speicherort wie ptr1 zeigt. Die Daten könnten die gleichen Zeiger haben, aber die Arrays, die ich denke, sind unterschiedlich. –

+0

Hmm, dieser: zurück ptr2; ist diesem hier zugeordnet: ptr2 = newArray (ptr, size); und dieses ptr2 wird in main veröffentlicht, also wo ist das Problem? Er kann den Zeiger nicht loslassen, bevor er ihn zurückgibt :-) aber da ptr2 in main und ptr2 in der newArray-Funktion gleich sind, gibt er alles frei -> ich gucke gerade erst bei ptr2. –

+0

Ja, ich denke, seine Sorge ist ungerechtfertigt. Also muss ich blind sein, weil ich kein Problem mit dem Code sehe. :-) –

0

Komm schon, ich sehe hier kein Problem. Aber ich denke, es lohnt sich, Ihnen zu sagen, dass ptr2 in der Hauptfunktion durch den zurückgegebenen Zeiger der newArray-Funktion zugewiesen wird und dass main-ptr2 logisch identisch mit newArray-ptr2 ist.

Wenn ich "logisch" sage, meine ich natürlich, sie sind zu verschiedenen Zeigern. Pointer ist ebenfalls variabel, also sind main-ptr2 und newArray-ptr2 zwei verschiedene Zeiger, sie sind an verschiedenen Stellen im Speicher gespeichert. Sie haben jedoch den gleichen Wert, der eine Adressinformation einer anderen Variablen im Speicher ist. Wenn sie den gleichen Wert haben, zeigen sie auf denselben Speicherblock.

Ich und mein Bruder sind zwei verschiedene Leute, ich deute auf eine schöne Frau und erzähle meinem Bruder "Hey, sieh dir diesen schönen Laien an!", Und nun zeigt mein Bruder auch auf diese hübsche Frau.

Also, zwei Zeiger, ein Ziel. Wenn Sie versuchen, das Ziel unter Verwendung von delete ptr2 in main freizugeben, wird das Ziel, auf das sowohl main-ptr2 als auch newArray-ptr2 zeigen, zerstört.

BTW, newArray-ptr2 eigentlich nicht mehr existiert, weil es sich um eine automatische Variable von newArray Funktion ist.

0

Denken Sie in Bezug auf Low-Level-Speicher Details. Innerhalb der newArray Funktion, die Sie einen Speicher Chunk durch neue zuweisen und die Basisadresse dieses Chunk zu ptr2 Zeiger zuweisen.

You, er dann wieder PTR2 Zeiger von der newArray Funktion und weisen diese Zeiger auf die PTR2 Zeiger innerhalb der main().

Letztlich befreien Sie die Chunk-Speicher von Ihnen durch die Anweisung löschen gehalten, wobei man die Maschine sagen, wies auf die zusammenhängend zugewiesenen Speicher chunk zu befreien, indem ptr2.

Ich sehe keinen Grund für irgendein Speicherleck.Zum besseren Verständnis würde ich empfehlen, dieses Programm über einen Debugger (gdb) auszuführen.

Verwandte Themen