6 Stimmen

Feststellen des Verhaltens von realloc() vor dessen Aufruf

So wie ich es verstanden habe, wird die Funktion realloc(), wenn sie aufgefordert wird, einen größeren Speicherblock zu reservieren, eine von drei verschiedenen Möglichkeiten nutzen:

if free contiguous block exists
    grow current block
else if sufficient memory
    allocate new memory
    copy old memory to new
    free old memory
else
    return null

Die Vergrößerung des aktuellen Blocks ist eine sehr billige Operation, also ist dies ein Verhalten, das ich gerne ausnutzen würde. Wenn ich jedoch Speicher neu zuweisen möchte, weil ich (zum Beispiel) ein Zeichen am Anfang einer bestehenden Zeichenkette einfügen möchte, möchte ich nicht, dass realloc() den Speicher kopiert. Am Ende kopiere ich die gesamte Zeichenkette mit realloc() und kopiere sie dann erneut manuell, um das erste Array-Element freizugeben.

Ist es möglich zu bestimmen, was realloc() tun wird? Wenn ja, ist es möglich, dies plattformübergreifend zu erreichen?

0voto

Jouni K. Seppänen Punkte 39674

Si Hindernisse für Ihren Speicherplatzbedarf geeignet sind, können Sie deren schnell wachsend Funktionalität. Obstacks sind eine Funktion der glibc, aber sie sind auch in der Freizügigkeit Bibliothek, die relativ portabel ist.

0voto

Jacob Krall Punkte 26956

Warum nicht etwas leeren Pufferraum links von der Zeichenkette lassen, etwa so:

char* buf = malloc(1024);
char* start = buf + 1024 - 3;
start[0]='t';
start[1]='o';
start[2]='\0';

So fügen Sie "on" an den Anfang Ihrer Zeichenkette an, um daraus "onto" zu machen \0 ":

start-=2;
if(start < buf) 
  DO_MEMORY_STUFF(start, buf);//time to reallocate!
start[0]='o';
start[1]='n';

Auf diese Weise müssen Sie Ihren Puffer nicht jedes Mal neu kopieren, wenn Sie eine Einfügung am Anfang vornehmen wollen.

Wenn Sie sowohl am Anfang als auch am Ende Einfügungen vornehmen müssen, sollten Sie an beiden Enden etwas Platz vorsehen; bei Einfügungen in der Mitte müssen Sie natürlich weiterhin Elemente umschichten.

0voto

vy32 Punkte 26016

Ein besserer Ansatz ist die Verwendung einer verknüpften Liste. Lassen Sie jedes Ihrer Datenobjekte auf einer Seite zuweisen, und weisen Sie eine andere Seite zu und haben Sie einen Link zu ihr, entweder von der vorherigen Seite oder von einer Indexseite. Auf diese Weise wissen Sie, wann die nächste Zuweisung fehlschlägt, und Sie müssen niemals Speicher kopieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X