PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++ Memoryleak?


Yavion
2010-06-20, 00:12:17
Hallo!

Ich möchte in C++ aus Eingabewerten ein Array von Ausgabewerten erstellen.
Die Größe kenne ich nicht, daher muss ich das Array auf dem Heap erstellen.

int* foobar(int eingabe[], int size){

int* fooArray = new int[size];

for (int i=0; i<size; i++)
{
fooArray[i]=eingabe[i];
}


return fooArray;

}

Nun frage ich mich: Wenn ich jetzt sowas mache wie

std::cout<<foobar(blahArray,blahSize);

Erzeuge ich da ein Memoryleak und wenn ja, wo kommt mein delete[] hin?
Oder ist der beschriebene Ansatz in C++ Mist und man sollte das RückgabeArray lieber grundsätzlich außerhalb erstellen und als Argument mit übergeben?

Danke schonmal!

RMC
2010-06-20, 00:21:43
RückgabeArray lieber grundsätzlich außerhalb erstellen und als Argument mit übergeben?

Ja, in dem Fall würde ich das bevorzugen. Erstellung und Zerstörung sollten eigentlich immer im selben Scope bzw. Objekt geschehen. Wenn die Funktion foobar() ein Objekt lokal erzeugt und einen Pointer zurückgibt, ist es sehr schwer nachzuvollziehen wer für das Aufräumen verantwortlich ist.

Gnafoo
2010-06-20, 02:25:09
Smart Pointer (bzw. ganz allgemein das RAII-Pattern) können das Problem auch recht elegant lösen:


#include <memory>
#include <iostream>
using namespace std;
using namespace std::tr1;

template<typename T>
struct ArrayDeleter
{
void operator()(T* ptr)
{
cout << "Delete" << endl;
delete[] ptr;
}
};

shared_ptr<int> foo()
{
cout << "Create" << endl;

int* fooArray = new int[5];
for (int i = 0; i < 5; i++) fooArray[i] = i;

return shared_ptr<int>(
fooArray, ArrayDeleter<int>()
);
}

int main()
{
cout << foo().get()[4] << endl;
return 0;
}


Ausgabe


Create
4
Delete


Mit boost::shared_array kann man sich den Delete-Funktor und den umständlichen Zugriff ersparen. Dafür ist diese Variante std::tr1-kompatibel.

Coda
2010-06-20, 14:37:37
Wobei shared_ptr Ref-Counting macht, was unter Umständen auch Performanceprobleme nach sich zieht wenn man es wirklich überall ohne zu überlegen verwendet.

Gast
2010-06-20, 19:19:47
Erzeuge ich da ein Memoryleak und wenn ja, wo kommt mein delete[] hin?
Oder ist der beschriebene Ansatz in C++ Mist und man sollte das RückgabeArray lieber grundsätzlich außerhalb erstellen und als Argument mit übergeben?

Danke schonmal!

In C++ erzeugt man in der Regel Objekte (Instanzen) von Klassen und die Objekte halten die Daten.
Der delete Befehl kommt dabei typischer in den Deconstruktor der Klasse.


Das was du versuchst ist die klassische funktionale Programmierung.


Memoryleaks kannst du mit Valgrind sehr leicht aufspüren.

Yavion
2010-06-22, 08:48:13
Danke Euch!