2008-10-24 9 views
5

Ich fange gerade an, C++ zu lernen, also entschuldige mich für diese einfache Frage. Ich lese Zahlen aus einer Datei ein und versuche dann, sie zu einem Array hinzuzufügen. Mein Problem ist, wie erhöhen Sie die Größe des Arrays? Zum Beispiel dachte, ich könnte nur tun können: einfach überschreibt den Wert, 5, dass ich anfangs auf x [0] und so gibt 0,6Dynamische Arrays

#include <iostream> 
using namespace std; 

int main() { 
    double *x; 
    x = new double[1]; 
    x[0]=5; 
    x = new double[1]; 
    x[1]=6; 
    cout << x[0] << "," << x[1] << endl; 
    return 0; 
} 

Aber dies offensichtlich. Wie würde ich es so machen, dass es 5,6 ausgeben würde?

Bitte beachten Sie, dass ich für das Beispiel, das ich eingefügt habe, wollte ich nicht mit dem Code aus einer Datei oder Code zu lesen, um die Zahlen von einem Benutzer zu bekommen. In der eigentlichen Anwendung weiß ich nicht, wie groß ein Array ist, das ich zur Kompilierzeit benötige, also bitte sage mir nicht, dass ich nur ein Array mit zwei Elementen erstellen soll und setze sie jeweils auf 5 und 6.

Danke für Ihre Hilfe.

Antwort

17

Sie möchten nicht direkt mit Arrays arbeiten. Verwenden Sie stattdessen eine vector. Dann können Sie die push_back Funktion aufrufen, um Dinge zum Ende hinzuzufügen, und es wird automatisch die Größe des Vektors für Sie ändern.

#include <iostream> 
#include <vector> 

int 
main() { 
    double value; 
    std::vector<double> values; 

    // Read in values 
    while (std::cin >> value) { 
     values.push_back(value); 
    } 

    // Print them back out 
    for (std::size_t i(0), len(values.size()); i != len; ++i) { 
     std::cout << values[i]; 
    } 
} 
+0

Sie müssen vorsichtig mit Vektor sein, aber sie neigen dazu, ziemlich langsam in der Verwendung sein. – Huppie

+0

Langsam ist relativ. Das heißt, profilieren Sie Ihr Programm und sehen Sie, ob es sich auf die Dinge auswirkt. Wenn dies der Fall ist, schreiben Sie einen benutzerdefinierten Zuordner, der für die Zuweisung von Doubles (und Objekten der Größe 'sizeof (double)') optimiert ist. –

+0

Es wird nicht langsamer als das Ändern der Größe mit neuen, löschen und kopieren. –

4

Sie sollten eine Collection-Klasse verwenden, um dies für Sie zu tun, anstatt es selbst zu verwalten. Schauen Sie sich die Klasse "vector" an. Es ist im Wesentlichen ein dynamisches Array, das bei Bedarf automatisch skaliert.

In Ihrer Situation würden Sie "Vektor" mit dem "doppelten" Typ verwenden. Möglicherweise müssen Sie auch Vorlagen in C++ lesen.

http://www.cplusplus.com/reference/stl/vector/

4

Oder, wenn Sie STL oder eine andere dynamische Sache nicht verwenden möchten, können Sie einfach das Array mit der richtigen Größe von Anfang an erstellen: x = new double [2];

Natürlich ist das Problem dort, wie groß es zu machen ist. Wenn Sie es nicht wissen, dann müssen Sie es einfach "groß genug" (wie einhundert oder tausend) erstellen ... das wird irgendwann nicht groß genug sein und es wird in einigen fehlschlagen zufällig aussehender Weg. Dann musst du die Größe ändern. Und wenn Sie diesen Punkt erreicht haben, würden Sie sich wünschen, dass Sie die STL von Anfang an benutzt hätten, wie die anderen Antworten Ihnen sagen.

#include <iostream> 
using namespace std; 
int main() { 
    double *x = new double[2]; 
    x[0]=5; 
    x[1]=6; 
    cout << x[0] << "," << x[1] << endl; 
    return 0; 
} 
2

Wenn Sie aus irgendeinem Grund keinen Zugriff auf STL - oder wollen lernen, wie dies selbst zu tun - Sie einen Algorithmus wie diese verwenden:

Ordnen Sie Ihre Array als eine willkürliche Größe, und denken Sie daran, wie viele Elemente in ihm sind und wie groß es ist:

int *a = malloc(int * ARBITRARY_SIZE); 
int size = 0; 
int allocated = ARBITRARY_SIZE; 

jedes Mal, wenn Sie ein neues Element hinzuzufügen, zu erhöhen „Größe“. Wenn die Größe gleich ARBITRARY_SIZE ist, multiplizieren Sie "allocated" mit 2 und weisen Sie das Array neu zu. Wie auch immer, weisen Sie den neuen Wert einer [Größe] zu.

void addElement(int value) { 
    ++size; 

    if (size == allocated) { 
    allocated *= 2; 
    a = realloc(sizeof(int) * allocated); 
    a = new_a; 
    } 

    a[size] = value; 
} 

Beachten Sie, dass der Code über mindestens einen Bug hat - Sie sind die Zuteilung nicht genug Platz für x [1] in jedem Fall.

Auch offensichtlich im realen Code würden Sie überprüfen, dass die Rückkehr von malloc & Realloc nicht null ist.

+0

Es ist auch traditionell, den Rückgabewert von malloc für null zu überprüfen. Im Gegensatz zu new wird std :: bad_alloc bei einem Fehler nicht geworfen, und Core-Dumps sind schwieriger zu debuggen als fehlgeschlagene Behauptungen ;-) –

+0

Änderungen vorgenommen. Obwohl Core-Dumps sind viel einfacher zu debuggen als die meisten anderen Bugs :) –

3

Hier ist ein Beispiel, obwohl für eine gute Maßnahme, so dass Sie das Muster sehen:

#include <iostream> 
using namespace std; 

int main() { 
    // Allocate some memory for a double array of size 1 and store 
    // an address to the beginning of the memory in mem_address. 
    double* mem_address = new double[1]; 

    // Assign 5 to the first element in the array. 
    mem_address[0] = 5; 

    // Save the address of the memory mem_address is currently 
    // referencing. 
    double* saved_address = mem_address; 

    // Allocate some memory for a double array of size 2 and store 
    // an address to the beginning of the memory in mem_address. 
    mem_address = new double[2]; 

    // Copy over the 1 element from the first memory block 
    // to the new one. 
    mem_address[0] = saved_address[0]; 

    // Done with the old memory, so clean it up. 
    delete [] saved_address; 

    // Assign 6 to the second element in the new array. 
    mem_address[1] = 6; 

    // Print out the 2 elements in the new array. 
    cout << mem_address[0] << "\n"; 
    cout << mem_address[1] << "\n"; 

    // Done with the new array memory now, so clean it up. 
    delete [] mem_address; 
} 
0

Ein Array braucht immer einen zusammenhängenden Speicherblock. In einer Situation, in der Sie das Array möglicherweise später ändern müssen, ist die Neuzuweisung wahrscheinlich die einzige Lösung. Dies ist, was Moishe und Shadow2531 oben tun.

Das Problem mit der Neuzuweisung ist, dass es eine kostspielige Operation sein kann. Wenn Sie also einem Array mit 5000 Elementen 5 weitere Elemente hinzufügen müssen, können Sie am Ende alle 5000 Elemente im Speicher kopieren.

Die Verwendung einer verketteten Liste kann stattdessen für ein solches Szenario in Betracht gezogen werden.

Verwandte Themen