2013-04-24 12 views
5

Alte Frage, aber ich habe noch ein paar Gedanken.Array in C, und sein Zeiger

char * getarrmal(void) 
{ 
    char *str; 
    str = (char *)malloc(10); 
    str[0] = 'a'; 
    str[1] = 'b'; 
    str[2] = 'c'; 
    str[3] = '\0'; 
    return str; 
} 

char * getarrdef(void) 
{ 
    char *str = "hello"; 
    return str; 
} 

char * getarrfix(void) 
{ 
    char str[10] = "world"; 
    return str; 
} 

Drei Funktionen. Die ersten beiden geben die Zeichenfolgenadresse zurück und die Zeichenfolge wird im Heap gespeichert, damit Sie sie beispielsweise in der Funktion main() weiterverwenden können.

In der letzten Funktion ist das Str eine lokale Variable und das zurückgegebene str kann nicht verwendet werden.

Meine Frage ist, wenn ich in der Funktion, die die ersten beiden ruft zurückgeben, sollte ich sie manuell freigeben? Es ist leicht zu glauben, dass der Fall malloc wahr ist, aber ich bin mir nicht sicher, ob das auch für char * str = "hallo" der Fall ist.

Wenn ich getarrdef() und nicht seinen Rückgabewert frei, habe ich irgendwie Speicherleck?

+3

Wenn Sie es zugewiesen haben und Sie nicht 'malloc' (oder einen seiner Cousins) dazu verwendet haben, rufen Sie nicht' free'. Einfach. –

Antwort

3

Nein, Sie sollten auf jeden Fall nicht versuchen, die zweite zu befreien. Es ist nicht im Heap gespeichert, sondern es ist ein String-Literal, und versuchen, es zu befreien ist undefiniertes Verhalten. Von C++11 7.21.3.3 The free function:

... wenn das Argument nicht ein Zeiger früher durch eine Speicherverwaltung Funktion zurückübereinstimmt, oder wenn der Raum durch einen Aufruf zu befreien oder realloc freigegeben worden ist, ist das Verhalten nicht definiert.

Für die erste, ja, es ist gute Praxis für die Verantwortung der zugewiesenen Speicher, um mit dem Speicher selbst zu übergeben. Das heißt, wenn etwas zugewiesen wird und Ihnen Sie sind dann verantwortlich für die Freigabe.

Das ist der Fall, auch wenn Sie es freigeben, indem Sie es an eine Funktion wie folgt übergeben: delarrmal() - damit haben Sie dieser Funktionsverantwortlichkeit gegeben, es zu befreien.

+0

Danke für Ihre schnelle Antwort :). Dann ist es ein bisschen interessant, wo ist die Str in der zweiten Funktion gespeichert, dem Stack des Aufrufers? – coldguy

+2

@coldguy, 'str' (der Zeiger) wird in den ersten beiden Fällen auf dem Stapel gespeichert, und' str' (das Array) wird dort für den dritten Fall gespeichert. Was jedoch der Zeiger _points to_ in den ersten beiden Fällen unterscheidet (der dritte Fall ist irrelevant, da str kein Zeiger (innerhalb der Funktion) ist). Im ersten Fall zeigt es auf den Heap, im zweiten Fall auf ein String-Literal, nicht im Heap. – paxdiablo

+0

Die Funktion oder das Modul, dem Speicher zugewiesen wurde, sollte es freigeben; Dinge herumreichen, um von anderen befreit zu werden, ist eine hervorragende Möglichkeit, Speicher zu verlieren oder auf Double-Free-Systemen abzustürzen. Aber am wichtigsten ist es, die Besitz-Semantik festzunageln und zu dokumentieren. Natürlich, wenn Sie die obsolete Sprache C aufgeben, kann die Weitergabe von Eigentumsrechten sicher durchgeführt werden, wie bei C++ 11's unique_ptr. –