Was ist der richtige Weg, um eine sehr große Struktur zu initialisieren?

StackOverflow https://stackoverflow.com/questions/177393

  •  05-07-2019
  •  | 
  •  

Frage

In unserem Code haben wir so etwas haben:

   *(controller->bigstruct) = ( struct bigstruct ){ 0 };
Diese

verwendet, um große zu arbeiten, und dann aufgerüstet wir Versionen von GCC und begann plötzlich Stapelüberlauf zu sehen. Mit Blick auf die Montage, die alte GCC-Code (2.x) war im Grunde dies zu tun:

memset(controller->bigstruct, 0, sizeof(struct bigstruct));

Die neue GCC (3.4.x) wurde dies zu tun

   struct bigstruct temp = { 0 };
   controller->bigstruct = temp;

Nach dem C99 spec Überprüfung, konnte ich sehen, warum; C99 erfordert im Allgemeinen, dass anonyme Strukturen auf dem Stack vorhanden sind. Es ist ein gutes Konzept, aber diese Struktur war 4 Megabytes groß, und immer nur auf Heap existieren sollte!

Wir haben gegriffen unsere eigene ‚initialisieren‘ Funktion zu machen, die explizit die Mitglieder setzen, aber das ist hässlich und eine Wartung Kopfschmerzen. Ich glaube nicht, eine richtige Lösung memset, weil ich nicht ein bisschen-Wert von 0 ist ein geeigneter Null-Wert für den Typen (Spitzfindigkeiten wissen kann, ich weiß, aber es gibt Sie, ich habe nichts dagegen, dass der Compiler tut es, weil es können weiß)

Was ist die „richtige“ oder zumindest am besten, weise eine große Struktur wie folgt zu initialisieren?

Um furthur zu klären, warum ich Memset denken ist keine Lösung: Die Regeln der Initialisierung der Mitglieder nicht ausdrücklich die gleichen wie statische Initialisierung initialisiert werden, und sind wie folgt:    - Wenn es Zeigertyp hat, wird er auf einen Null-Zeiger initialisiert;    - Wenn es arithmetisch-Typen hat, wird sie an (positiv oder unsigned) initialisiert, Null ist;    ...

‚Memset‘ wird der Speicher auf Bitmusterebene Null gesetzt, was nicht unbedingt dasselbe ist. Stellen Sie sich ein System, das IEEE Floating-Point keine Nummern verwenden. Ungewöhnlich, aber unterstützt durch C. Die Darstellung von 0.0 nicht bedeuten muss „alle Bits Null“, ist es etwas bequemer an den Prozessor sein könnte.

War es hilfreich?

Lösung

memset ist der Weg zu gehen. Sie haben nicht viele Alternativen haben.

Sie so etwas wie:

#define InitStruct(var, type) type var; memset(&var, 0, sizeof(type))

Damit Sie nur haben:

InitStruct(st, BigStruct);

Und dann verwendet st wie gewohnt ...

ich nicht, wie „0“ ist kein gültiger „0“ Typ für eine Struktur. Der einzige Weg, um „Masse initialisieren“ eine Struktur ist, alle seine Speicher auf einen Wert zu setzen; sonst würden Sie zusätzliche Logik machen müssen, um es zu sagen, ein bestimmtes Bitmuster pro Mitglied zu verwenden. Der beste „generic“ Bitmuster 0 zu verwenden.

Außerdem - das ist die gleiche Logik, die Sie beim tun

*(controller->bigstruct) = *( struct bigstruct ){ 0 };

Deshalb werde ich nicht Ihre Abneigung, es zu benutzen:)

Der erste Kommentar zu diesem Beitrag hat mich einige der Forschung, bevor ich ihn und Idiot genannt und ich fand diese:

http://www.lysator.liu.se/ c / c-faq / c-1.html

Sehr interessant; wenn ich wählen Sie-up könnte einen Kommentar würde ich:)

Dass gesagt wird -. Ihre einzige Option, wenn Sie archaische Architekturen mit nicht-0 NULL-Werten ausrichten mögen noch manuelle Initialisierung an bestimmten Mitglieder zu tun

Danke Thomas Padron-McCarthy! Ich lernte etwas Neues heute:)

Andere Tipps

Wenn Sie nicht memset verwenden möchten, könnten Sie immer eine statische Kopie Ihrer Struktur und Verwendung Memcpy erklären, die eine ähnliche Leistung geben. Dies fügt 4 megs zu Ihrem Programm ist aber wahrscheinlich besser als einzelne Elemente zu setzen.

Das heißt, wenn GCC Memset wurde mit, und es war gut genug, um vorher, würde ich vorschlagen, es jetzt gut genug ist.

Wie andere gesagt haben, memset ist der Weg zu gehen. Allerdings nicht Verwendung memset auf C ++ Objekte, insbesondere solche mit virtuellen Methoden. Die sizeof( foo ) wird die Tabelle der virtuellen Funktionszeiger umfassen, und auf dass ein memset tun wird ernst Kummer verursachen.

Wenn Memset löst nicht das Problem von selbst, machen Sie einfach eine Memset und und initialisieren alle Elemente, die nicht Null ist (dh Ihre Nicht-IEEE-Gleitkomma-Werte) sein sollte.

Privat Initialisierungsfunktion ist nicht hässlich eher eine gute OO Art und Weise Objekte (structs) zu initialisieren. Ich gehe davon aus, dass Ihre Struktur nicht 4MB von Zeigern ist, so würde ich davon ausgehen, dass die Lösung so sein sollte:

void init_big_struct(struct bigstruct *s)  
{  
    memset(s, 0, sizeof(struct bigstruct));  
    s->some_pointer = NULL; // Multiply this as needed  
}

Von anderer Seite unseres Code wird auf mehr als 20 Embedded-Betriebssysteme und ein große Anzahl unterschiedlicher Geräte läuft, trifft nie ein Problem mit nur der Struktur memset.

hmm - zunächst eine init-Funktion machen und jedes Mitglied explizit IST DIE RICHTIGE Einstellung -. Es, s die Art und Weise Bauer in OO-Sprachen arbeitet

und zweite - weiß jemand eine Hardware, die nicht IEEE Gleitkommazahlen implementiert? - vielleicht Commodore 64 oder somethig; -)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top