Ich möchte wissen, welche Funktionen der C-Standardbibliothek malloc
und free
unter der Haube verwenden. Es sah für mich so aus, als ob printf
malloc
verwenden würde, aber als ich ein Programm mit valgrind
getestet habe, ist mir aufgefallen, dass printf
Aufrufe keinen Speicher mit malloc
zugewiesen haben. Woher? Wie verwaltet es dann die Erinnerung?
Normalerweise sind die einzigen Routinen im C99-Standard, die malloc()
verwenden können, die Standard-I / O-Funktionen (in <stdio.h>
, wobei die Dateistruktur und der von ihr verwendete Puffer oft wie von malloc()
zugewiesen wird. Ein Teil der Gebietsschemabehandlung kann dynamischen Speicher verwenden, alle anderen Routinen benötigen im Allgemeinen keine dynamische Speicherzuweisung.
Nun, ist das irgendwie dokumentiert? Nein, ich glaube nicht. Es gibt keine pauschale Einschränkung 'die Funktionen in der Bibliothek dürfen nicht malloc()
' verwenden. (Es gibt jedoch Einschränkungen für andere Funktionen wie strtok()
und srand()
und rand()
; sie dürfen nicht von der Implementierung verwendet werden, und die Implementierung darf keine der anderen Funktionen verwenden, die einen Zeiger zurückgeben könnten zu einem statischen Speicherort.) Einer der Gründe, warum die extrem nützliche strdup()
-Funktion nicht in der Standard-C-Bibliothek ist, ist (wie berichtet), weil sie die Speicherzuweisung durchführt. Es ist auch nicht völlig klar, ob dies ein Faktor in den Routinen wie asprintf()
und vasprintf()
in TR 24731-2 war, der es nicht in C1x geschafft hat, aber es könnte ein Faktor gewesen sein.
Der Standard stellt keine Anforderungen an die Implementierung, AFAIK.
Ich weiß nicht genau, wie printf
implementiert ist, aber von ganz oben kann ich mir keinen Grund vorstellen, warum es Speicher dynamisch zuweisen müsste. Sie können sich immer die Quelle für Ihre Plattform ansehen.
Es hängt davon ab, welche libc
Sie verwenden. Es sollte keine Einschränkung für die C-Spezifikation und bis zur Implementierung geben.
Zum Beispiel wird newlib printf
normalerweise mit der Verwendung von Speicher auf Stack-Rahmen gemacht, aber wenn es wirklich nötig ist, ruft es eine interne Funktion _malloc_r()
direkt auf.
Ich habe valgrind
nicht verwendet, ich bin mir nicht sicher, ob es die Verwendung von _malloc_r()
erkennen kann.
Weder der C- noch der POSIX-Standard zwingen die Implementierer dazu, malloc()
zu verwenden, daher gibt es keine allgemeine Antwort auf Ihre Frage.
Jede Implementierung einer normalen Standardbibliothek, die malloc()
in einer ihrer Funktionen verwendet, setzt jedoch errno
auf ENOMEM
, wenn malloc()
fehlschlägt. Daher können Sie aus der Dokumentation ableiten, ob eine Bibliotheksfunktion malloc()
verwendet oder nicht. Punkt für Fall: Auf meinem System kann mmap()
malloc()
verwenden, da mmap()
errno
auf ENOMEM
setzen kann.
Das heißt, mit valgrind
ist ein schlechter Weg herauszufinden, ob eine bestimmte Funktion malloc()
aufruft oder nicht. Betrachten Sie das folgende Stück Code:
Wenn Sie diese Funktion mit einem anderen Argument als 0
aufrufen, wird valgrind nicht bemerken, dass sie tatsächlich malloc()
aufrufen kann. Stellen Sie sich valgrind
als virtuelle Maschine vor (da es das ist): Es schaut nicht auf Ihren Code, er sieht nur, was die Maschine tatsächlich ausführen würde.
printf muss nicht die gesamte Ausgabezeichenfolge in einer Aufnahme erstellen, sondern kann sie Stück für Stück ausgeben. Wenn sie auf einen Formatbezeichner trifft, kann sie diese Datenmenge so ausgeben, wie sie erstellt wird, und fortfahren mit dem Rest der Zeichenfolge.
Es wird höchstens ein lokal definiertes Array von Zeichen (auf dem Stapel) benötigt, das groß genug ist, um die größte Ganzzahl oder Fließkommazahl zu enthalten, die es verarbeiten kann, die nicht sehr groß ist.
Tags und Links c x86 linux memory-management