c / expert
Snippet
Delegierung und Weiterleitung variadischer Argumente durch va_list-Kopieren
Dieses Beispiel veranschaulicht die sichere zweiphasige Verarbeitung variadischer Argumente mittels stdarg-Makros in C. Die Funktion dupliziert den va_list-Status mit va_copy, um zuerst die Ausgabelänge über vsnprintf(NULL, 0, ...) zu ermitteln, allokiert einen exakten Puffer und nutzt die ursprüngliche va_list zur sicheren Formatierung.
snippet.c
c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>#include <stdarg.h>#include <stdlib.h>void vformat_and_dispatch(void (*consumer)(const char *), const char *fmt, va_list args) {va_list args_copy;va_copy(args_copy, args);int len = vsnprintf(NULL, 0, fmt, args_copy);va_end(args_copy);if (len < 0) return;char *buf = (char *)malloc((size_t)len + 1);if (!buf) return;vsnprintf(buf, (size_t)len + 1, fmt, args);consumer(buf);free(buf);}void print_consumer(const char *text) {printf("OUTPUT: %s\n", text);}void log_wrapper(const char *fmt, ...) {va_list args;va_start(args, fmt);vformat_and_dispatch(print_consumer, fmt, args);va_end(args);}
Erklärung
1
va_copy(args_copy, args);
Erstellt einen unabhängigen Klon des va_list-Zustands für mehrfache Lesedurchläufe.
2
int len = vsnprintf(NULL, 0, fmt, args_copy);
Führt eine Test-Formatierung durch, um die erforderliche Puffergröße zu berechnen.
3
va_end(args_copy);
Gibt die Ressourcen des geklonten variadischen Iterators frei.
4
vsnprintf(buf, (size_t)len + 1, fmt, args);
Rendert den formatierten Text unter Verwendung des ursprünglichen Iterators in den Speicherpuffer.
5
va_start(args, fmt);
Initialisiert den variadischen Iterator im Anschluss an den benannten Formatstring-Parameter.