2012-12-23 6 views
5

Kann ähnliche Frage auf SO gefunden werden. Aber habe ich nicht gefunden, dass, hier ist das Szenariomit Malloc über Array

Fall 1

void main() 
{ 
    char g[10]; 
    char a[10]; 
    scanf("%[^\n] %[^\n]",a,g); 
    swap(a,g); 
    printf("%s %s",a,g); 
} 

Fall 2

void main() 
{ 
    char *g=malloc(sizeof(char)*10); 
    char *a=malloc(sizeof(char)*10); 
    scanf("%[^\n] %[^\n]",a,g); 
    swap(a,g); 
    printf("%s %s",a,g); 
} 

Ich bin immer gleiche Leistung in beiden Fällen. Also, meine Frage ist, wann sollte ich malloc() anstelle von array oder umgekehrt bevorzugen und warum ?? Ich fand allgemeine Definition, malloc() bietet dynamische Zuordnung. Also, es ist der einzige Unterschied zwischen ihnen ?? Bitte erklären Sie mit einem Beispiel, was die Bedeutung von dynamic ist, obwohl wir die Größe in malloc() angeben.

+2

'sizeof char' ist immer' 1' FYI –

Antwort

6

Der prinzipielle Unterschied bezieht sich auf wann und wie Sie die Array-Länge entscheiden. Wenn Sie Arrays fester Länge verwenden, müssen Sie Ihre Array-Länge zum Zeitpunkt der Kompilierung festlegen. Im Gegensatz dazu können Sie mit der Option malloc die Array-Länge zur Laufzeit festlegen.

Insbesondere bei der Entscheidung zur Laufzeit können Sie die Entscheidung auf Benutzereingaben basieren, auf Informationen, die zum Zeitpunkt der Kompilierung nicht bekannt waren. Zum Beispiel können Sie das Array einer Größe zuweisen, die groß genug ist, um den tatsächlichen Dateneingaben des Benutzers zu entsprechen. Wenn Sie Arrays fester Länge verwenden, müssen Sie zur Kompilierungszeit eine obere Grenze festlegen und diese Beschränkung dann auf den Benutzer anwenden.

Ein weiteres subtileres Problem ist, dass die Zuweisung sehr großer Arrays fester Länge als lokale Variablen zu Fehlern beim Stack-Überlauf führen kann. Aus diesem Grund bevorzugen Sie manchmal, solche Arrays dynamisch unter Verwendung von malloc zuzuweisen.

+0

Ich werde schätzen, wenn Sie mit einigen Beispielen erklären – Ravi

+1

@var___ Siehe meine Antwort (und versuchen, die Mühe zu machen, dies zu verstehen, ist es etwas sehr einfaches ...) –

+0

Ya, ich versuche, eine Sache, die mich jedes Mal verwirrt, das Wort 'dynamisch'. Vielleicht versuche ich, aus deiner Antwort herauszufinden. – Ravi

2

Bitte erklären Sie mit einem Beispiel, was ist die Bedeutung von dynamischen, obwohl wir die Größe angeben.

Ich vermute, dass dies vor C99 signifikant war. Vor C99 konnten Sie keine dynamisch sortierten Auto-Arrays haben:

void somefunc(size_t sz) 
{ 
    char buf[sz]; 
} 

ist gültig C99 aber ungültig C89. Mit malloc() können Sie jedoch einen beliebigen Wert angeben. Sie müssen malloc() nicht mit einer Konstanten als Argument aufrufen.

auch zu klären, was andere Zwecke malloc() hat: Sie nicht stapelzugewiesenen Speicher aus einer Funktion zurückgeben kann, so dass, wenn Ihre Funktion zugewiesenen Speicher zurückgeben muss, Sie in der Regel malloc() (oder ein anderes Mitglied der malloc verwenden Familie, einschließlich realloc() und calloc()), um einen Speicherblock zu erhalten. Um dies zu verstehen, sollten Sie den folgenden Code ein:

char *foo() 
{ 
    char buf[13] = "Hello world!"; 
    return buf; 
} 

Da buf ist eine lokale Variable, wird es am Ende seiner einschließenden Funktion für ungültig erklärt - Rückkehr in undefiniertem Verhalten führt. Die obige Funktion ist fehlerhaft. jedoch ein Zeiger mit malloc() erhalten bleibt gültig bis zum Funktionsaufrufe (bis Sie nicht free() auf sie rufen Sie):

char *bar() 
{ 
    char *buf = malloc(13); 
    strcpy(buf, "Hello World!"); 
    return buf; 
} 

Diese absolut gültig ist.

0

Ich würde hinzufügen, dass malloc() in diesem speziellen Beispiel sehr verschwenderisch ist, da mehr Speicher für das Array reserviert ist als aufgrund von Overhead in malloc und der Zeit, die zum Aufrufen von malloc benötigt wird() und später frei() - und es gibt Overhead für den Programmierer zu erinnern, es zu befreien - Speicherlecks können ziemlich schwer zu debuggen sein.

Edit: Fall in Punkt, fehlt Ihrem Code die freie() am Ende der wichtigsten() - mag hier keine Rolle spielen, aber es zeigt meinen Punkt ganz gut.

Daher sollten kleine Strukturen (weniger als 100 Bytes) normalerweise auf dem Stapel zugeordnet werden. Wenn Sie große Datenstrukturen haben, ist es besser, sie mit malloc zu belegen (oder, wenn es das Richtige ist, globals zu verwenden - aber das ist ein heikles Thema).

Klar, wenn Sie nicht wissen, die Größe von etwas im Voraus, und es kann sehr groß sein (Kilobyte in der Größe), ist es definitiv ein Fall von "in Betracht ziehen, malloc".

Auf der anderen Seite sind Stacks heutzutage ziemlich groß (zumindest für "echte Computer"), also ist es nicht so wichtig, ein paar Kilobyte Stack zuzuteilen.

+0

Dieser Hinweis ist in Ordnung, solange Sie zur Kompilierungszeit wissen, wie viel Speicher benötigt wird. –

+0

Ja, oder zumindest wissen Sie, dass "es nicht mehr sein wird, und überprüfen Sie, dass es nicht mehr ist". Ich mag einfach nicht den allgemeinen Vorschlag "benutze malloc, wenn du die Größe der Eingabe nicht kennst" - es ist vollkommen in Ordnung, einen 1000-Zeichen-Puffer zu haben, um einen Dateinamen einzugeben, du musst den Dateinamen nicht nach getchar und Realloc, wie Sie gehen, um sicherzustellen, dass es perectly übereinstimmt ... –