Programmieren - alles kontrollieren 4.940 Themen, 20.676 Beiträge

C++: Frage zu Zeigern

Yves3 / 9 Antworten / Flachansicht Nickles

Hallo

Wie kann ich so etwas:

int* pStructure = new int[1];

.. während der Laufzeit noch vergrössern, ohne einen vollkommen neuen Speicherbereich zu reservieren?
Einfach so, dass die vorhandenen Daten so bleiben wie sie sind und das Array noch etwas mehr Platz hat.
Ich möchte das nach Möglichkeit ohne std::vector machen.

Schon mal Danke!

bei Antwort benachrichtigen
mr.escape Yves3 „Heute wollte ich diesen Code noch in einer Funktion kapseln. Warum erhalte ich...“
Optionen

Was auf jeden fall falsch ist, ist die übergabe von p_iArray in CUtilities::ResizeArray. Der parameter ist die alte adresse des arrays, dessen inhalt in einen neu allozierten bereich kopiert wird. Dieser neue bereich geht aber verloren, weil die übergabe der adresse "by value" erfolgt, d.h. nur die kopie der adresse angepasst wird und diese mit der beendigung der funktion verloren geht (sog. automatische stackvariable).
Stattdessen muss die adresse der adresse übergeben werden, also int** p_iArray.
Das ergibt:
void CUtilities::ResizeArray(int** p_iArray, int iNewSize, int iOldSize){
    int* NewArray = new int[iNewSize];

    for(int i=0;i<iOldSize;i++)
        NewArray[i]=(*p_iArray)[i];

    delete[] *p_iArray;
    *p_iArray = NewArray;
}

und beim aufruf
Utilities.ResizeArray(&p_iArray, 20, 300);
Das ist auch die ursache für den fehler, weil die alte adresse, die in der vergrößerungsfunktion eben nicht angepasst wird, immer noch auf den freigegebenen bereich verweist. Der zugriff darauf löst dann den fehler aus.

Noch einfacher ist in diesem fall aber die verwendung von referenzen. Die einzige änderung ist ein "&" in:
void CUtilities::ResizeArray(int *&p_iArray, int iNewSize, int iOldSize)
Damit wird die parameterübergabe für diesen parameter von "by value" auf "by reference" umgestellt.
Für den compiler ist es ziemlich genau das selbe, wie bei der "doppelten adresse", es ist aber im gegensatz dazu nicht möglich die referenz selbst zu ändern, sondern nur die referenzierten objekte. Die folge ist eine geringere flexibilität bei komplexeren arrays.

mr.escape

"The man who trades freedom for security does not deserve nor will he ever receive either." - Benjamin Franklin"Wer seine Freiheit aufgibt, um Sicherheit zu erreichen, wird beides verlieren." - Georg Christoph Lichtenberg
bei Antwort benachrichtigen