2016-04-07 9 views
0

Ich möchte die Größe des Arrays ändern, wenn es sein Limit überschreitet. Ich habe dafür eine Funktion erstellt.Eigene Realloc implementieren

void AddElemenet(int i , int value){ 

    if(i > index - 1){ 
    int tmp = index; 
    double *new_arr; 
    while(i > tmp){ 
     tmp*=2 
    } 
    new_arr = new double[tmp](); 
    for(int j = 0; j < index ; j++){ 
     new_arr[j] = arr[j]; 
    } 
    index = tmp; 
    delete[] arr; 
    arr = new_arr; 
    } 
    arr[i] = value; 

} 

Index bezieht sich auf die maximale Größe eines Arrays; und arr ist ein dynamisch zugewiesenes Array unter Verwendung von new selbst. Das Problem ist, dass ich arr einer lokalen Variable, die zerstört wird, zuweisen. Ich habe versucht, es als Reference oder Zeiger mit *arr=*new_arr

, aber nichts funktioniert bis jetzt. Wie kann ich das Array mit dieser lokalen Variable ändern?

+0

ist 'ein Array arr'? oder ein Zeiger? – vu1p3n0x

+0

seine dynamisch zugewiesene Array mit neuen. Ich werde es der Frage Info hinzufügen. – user3706129

+3

Ich sehe nichts falsch mit diesem (neben der Verwendung von 'new' und' delete' in C++, das ist ein anderes Problem). 'arr' zeigt auf das neu zugewiesene Array (auf das' new_arr' zeigt). – Kevin

Antwort

4

Die verschiedenen Fehler in Ihrer Implementierung zeigen, warum es fast immer eine gute Idee ist, die Standardbibliothek zu verwenden. Es wäre sehr einfach, std::vector an diese Schnittstelle anzupassen.

Die Essenz Ihres Problems ist die Verwirrung über was index bedeutet. (Das ist ein schrecklicher Name für eine Member-Variable. Es sagt nichts. Index von was? Und eigentlich ist es kein Index; es ist die Größe des Arrays. Zumindest sollte es sein.)

Angenommen, dass Ihre Array hat 4 Elemente, also index ist 4 (basierend auf der Annahme, dass es die Größe des Arrays ist). Jetzt möchten Sie AddElement(4, 42);. Die Bedingung in if(i > index - 1) ist sicherlich wahr: i ist 4, und index - 1 ist 3. So wird der Neuzuweisungsblock eingegeben. Das erste, was Sie tun, ist jedoch tmp = index; while(i > tmp) tmp *= 2;. i ist nicht größer als tmp - beide sind 4 - so wird die Schleife nie ausgeführt und tmp wird immer noch 4 sein. Jetzt ordnen Sie ein neues Array mit vier Elementen zu, kopieren die vorhandenen vier Elemente, "updaten" index auf 4 (den aktuellen Wert) und löschen das alte Array. Gleich danach versuchen Sie, das Element mit dem Index 4 auf 42 zu setzen. Aber das Array hat nur vier Elemente, das heißt Undefined Behavior.

Da Sie die Größe des Arrays oder den Wert index, der seine Größe angibt, nicht geändert haben, wird Ihr späterer Versuch, die Werte des Arrays zu drucken, mit der tatsächlichen Größe angehalten, wobei der Wert außerhalb des Bereichs ignoriert wird (., die zu einer anderen Datenstruktur gehören können, so dass ihr Wert bedeutungslos ist sowieso) Speicherbereich des Arrays

Wenn Sie index als size und tmp als new_size umbenennen, wird der Code viel klarer, und die Lösung ist auch klar:

if (i >= size) { 
    size_t new_size = size; 
    while (i >= new_size) new_size *= 2; /* NOT > */ 
    double* new_array = new double[new_size](); 
    for (size_t j = 0; j < size; ++j) new_array[j] = array[j]; 
    array = new_array; 
    size = new_size; 
} 
array[i] = value; 

Dies würde alle haben viel einfacher und weniger fehleranfällig, wenn Sie ein std::vector verwendet:

class MyVector { 
    public: 
    void AddElement(size_t i, double value) { 
     if (i >= data_.size()) data_.resize(i + 1); 
     data_[i] = value; 
    } 
    /* Many implementation details omitted */ 
    private: 
    std::vector<double> data_; 
} 
0
std::vector <int> list;  

void AddElemenet(int value) 
{ 
    list.push_back (value);  
} 

Verwenden Sie einfach Vektor. Array-Größe ist festgelegt. Die Größe des Vektors ist dynamisch.