array vom Typ void
plain C haben nettes feature - void-Typ, Pointer, die verwendet werden kann als Zeiger auf einen beliebigen Datentyp.
Aber, angenommen ich habe folgende struct:
struct token {
int type;
void *value;
};
denen Wert-Feld kann die Punkt-zu-char-array, oder int, oder etwas anderes.
Also, wenn die Zuweisung eine neue Instanz von diesem struct brauche ich:
1) Speicher für das struct;
2) Speicher für Wert und weisen Sie es auf dem Wert-Feld.
Meine Frage ist - gibt es Möglichkeiten, um zu erklären, "array vom Typ void", die gegossen werden Sie zu einer anderen Art wie der void-pointer?
Alles was ich will ist die Verwendung von "flexiblen Element Arrays" (siehe 6.7.2.1 der C99-standard) mit der Fähigkeit zum casting zu jedem Typ.
Etwas wie dieses:
struct token {
int type;
void value[];
};
struct token *p = malloc(sizeof(struct token) + value_size);
memcpy(p->value, val, value_size);
...
char *ptr = token->value;
Ich nehme an, deklarieren token->Wert als char-oder int-array und Umwandlung in den benötigten Typ später wird diese Arbeit zu tun, aber kann sehr verwirrend für jemanden, der gelesen wird dieser code später.
mit
char[]
ist in Ordnung imho, da sizeof(char) == 1
und du wirst nie überrascht. Vielleicht möchten Sie erwägen den Makros zum Zugriff p->value
mit dem richtigen Typ.InformationsquelleAutor S.J. | 2011-04-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Naja, irgendwie schon, aber es ist wahrscheinlich nicht etwas, was Sie wollen:
Das folgende makro kann verwendet werden, um die index-Daten (vorausgesetzt
x
ist einstruct token *
):Und, wenn Sie möchten, können Sie das folgende makro können wickeln Sie Ihre
make_token
- Funktion, um es ein wenig intuitiver (oder mehr hackish, wenn Sie darüber nachdenken, es auf diese Weise):Verwendung:
InformationsquelleAutor Chris Lutz
Ich würde wahrscheinlich tun Sie dies:
Bearbeiten, eigentlich muss man zu festgelegten diejenigen p.Wert[index] = somethings. Und/oder verwenden Sie eine union nicht zu typisieren.
p.value
bevor Sie es verwenden.p.value[0] = something
ergibt einen compile-Zeit-Fehler, sicherlich? Kann man nicht dereferenzieren einevoid*
.Das wird nicht mal kompilieren. Einige Compiler können Zeiger-Arithmetik auf
void *
Zeiger (wie eine Erweiterung), aber alle von Ihnen verbieten dereferenzieren void-Pointer.InformationsquelleAutor old_timer
Können Sie nicht ein array von 'void' - Elemente, aber Sie sollten in der Lage sein, etwas zu tun, was Sie wollen, solange Sie wissen, value_size, wenn Sie das tun malloc. Aber es wird nicht schön werden.
Beachten Sie, dass müssen Sie eine zusätzliche Adresse-von-operator, wenn Sie wollen, um den zusätzlichen Speicher.
Wird dieser "Abfall" sizeof(void*) bytes, und die ursprüngliche Art der
value
spielt eigentlich keine Rolle, also kann man da auch ein kleineres Element. Ich würde wahrscheinlichtypedef char placeholder;
und machenvalue
.InformationsquelleAutor AShelly
Erweiterung auf AShelly die Antwort, die Sie dies tun können;
Beachten Sie die Verwendung von "offsetof()" anstelle von "sizeof()" bei der Zuteilung von Arbeitsspeicher zu vermeiden, verschwenden die "void *buf;" Feld Größe. Die Art von "buf" nicht so schlimm, aber mit "void *" bedeutet, es wird ausrichten, dass die "buf" - Feld in der Struktur optimal für einen Zeiger, hinzufügen Polsterung, bevor es, falls erforderlich. Dieser bietet in der Regel bessere Speicher-Ausrichtung für die Einträge, besonders dann, wenn Sie mindestens so groß wie ein pointer.
Zugriff auf die Einträge im buffer sieht wie folgt aus;
Beachten Sie die zusätzliche Adresse-von-operator, um die Adresse der "buf" - Feld als Ausgangspunkt für die zugewiesenen Eintrag Speicher.
InformationsquelleAutor Donovan Baarda
folgende Struktur kann Ihnen helfen.
Mehr Details : clibutils
InformationsquelleAutor Avinash