wake-up-neo.com

Wie kann man in C ++ "neu zuordnen"?

Wie kann ich realloc in C++? Es scheint in der Sprache zu fehlen - es gibt new und delete, aber nicht resize!

Ich brauche es, weil mein Programm mehr Daten liest und ich den Puffer neu zuweisen muss, um ihn zu speichern. Ich halte es nicht für die richtige Option, delete den alten Zeiger und new einen neuen, größeren Zeiger zu setzen.

77
bodacydo

Verwenden Sie :: std :: vector!

Type* t = (Type*)malloc(sizeof(Type)*n) 
memset(t, 0, sizeof(Type)*m)

wird

::std::vector<Type> t(n, 0);

Dann

t = (Type*)realloc(t, sizeof(Type) * n2);

wird

t.resize(n2);

Wenn Sie Zeiger in Funktion übergeben möchten, statt

Foo(t)

verwenden

Foo(&t[0])

Es ist absolut korrekter C++ - Code, da vector ein intelligentes C-Array ist.

47
f0b0s

Die richtige Option ist wahrscheinlich, einen Container zu verwenden, der die Arbeit für Sie erledigt, wie std::vector.

new und delete können die Größe nicht ändern, da sie gerade genug Speicher für ein Objekt des angegebenen Typs reservieren. Die Größe eines bestimmten Typs wird sich nie ändern. Es gibt new[] und delete[] aber es gibt kaum einen Grund, sie zu benutzen.

Was realloc in C tut, ist wahrscheinlich nur ein malloc, memcpy und free, obwohl Speichermanager etwas Kluges tun dürfen, wenn sie es tun Es ist genügend zusammenhängender freier Speicher verfügbar.

45
Thomas

Das Ändern der Größe in C++ ist umständlich, da Konstruktoren und Destruktoren aufgerufen werden müssen.

Ich glaube nicht, dass es einen fundamentalen Grund dafür gibt, dass Sie in C++ keinen resize[] - Operator für new[] Und delete[] Haben können, der etwas Ähnliches bewirkt:

newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;

Offensichtlich würde oldsize von einem geheimen Ort abgerufen werden, genauso wie es in delete[] Ist, und Type würde vom Typ des Operanden stammen. resize[] Würde fehlschlagen, wenn der Typ nicht kopierbar ist - was richtig ist, da solche Objekte einfach nicht verschoben werden können. Schließlich erstellt der obige Code die Objekte standardmäßig, bevor er sie zuweist, was Sie als tatsächliches Verhalten nicht wünschen würden.

Es gibt eine mögliche Optimierung, bei der newsize <= oldsize Destruktoren für die Objekte "nach dem Ende" des neu zusammengestellten Arrays aufruft und nichts anderes tut. Der Standard müsste definieren, ob diese Optimierung erforderlich (wie bei resize() einem Vektor), zulässig, aber nicht angegeben, zulässig, aber implementierungsabhängig oder verboten ist.

Die Frage, die Sie sich dann stellen sollten, lautet: "Ist es tatsächlich sinnvoll, dies bereitzustellen, da vector dies auch tut, und wurde speziell entwickelt, um einen Container mit veränderbarer Größe (mit zusammenhängendem Speicher - diese Anforderung entfällt) bereitzustellen in C++ 98, aber behoben in C++ 03) passt das besser als Arrays mit den C++ - Methoden? "

Ich denke, die Antwort wird allgemein als "nein" angesehen. Wenn Sie die Größe von Puffern nach C-Art ändern möchten, verwenden Sie malloc / free / realloc, Die in C++ verfügbar sind. Wenn Sie die Größe von Puffern in C++ ändern möchten, verwenden Sie einen Vektor (oder deque, wenn Sie keinen zusammenhängenden Speicher benötigen). Versuchen Sie nicht, die beiden Werte mit new[] Für unformatierte Puffer zu mischen, es sei denn, Sie implementieren einen vektorähnlichen Container.

33
Steve Jessop